hashtable optimized
This commit is contained in:
parent
f9a844447d
commit
756a0494af
@ -3,17 +3,18 @@
|
||||
define_Autoarr2(KeyValuePair)
|
||||
|
||||
// amount of rows
|
||||
static const uint16 HT_HEIGHTS[]={61,631,3889,19441,65521};
|
||||
#define HT_HEIN_MIN 0
|
||||
#define HT_HEIN_MAX 5
|
||||
static const uint16 HT_HEIGHTS[]={61,257,1021,4099,16381,65521};
|
||||
|
||||
#define ARR_BC 16
|
||||
#define ARR_BL 128
|
||||
#define ARR_BC 2
|
||||
#define ARR_BL 8
|
||||
|
||||
Hashtable* Hashtable_create(){
|
||||
Hashtable* ht=malloc(sizeof(Hashtable));
|
||||
//ht->hein=0;//
|
||||
ht->hein=1;
|
||||
ht->rows=malloc(HT_HEIGHTS[ht->hein]*sizeof(Autoarr2(KeyValuePair)));
|
||||
for(uint16 i=0;i<HT_HEIGHTS[ht->hein];i++)
|
||||
ht->hein=HT_HEIN_MIN;
|
||||
ht->rows=malloc(HT_HEIGHTS[HT_HEIN_MIN]*sizeof(Autoarr2(KeyValuePair)));
|
||||
for(uint16 i=0;i<HT_HEIGHTS[HT_HEIN_MIN];i++)
|
||||
ht->rows[i]=Autoarr2_create(KeyValuePair,ARR_BC,ARR_BL);
|
||||
return ht;
|
||||
}
|
||||
@ -32,27 +33,33 @@ void Hashtable_free(Hashtable* ht){
|
||||
uint32 Hashtable_height(Hashtable* ht){ return HT_HEIGHTS[ht->hein]; }
|
||||
|
||||
|
||||
void Hashtable_resize(Hashtable* ht){printf("RESIZE\n");
|
||||
void Hashtable_expand(Hashtable* ht){
|
||||
if(ht->hein>=HT_HEIN_MAX) throw(ERR_MAXLENGTH);
|
||||
Autoarr2(KeyValuePair)* newrows=malloc(HT_HEIGHTS[++ht->hein]*sizeof(Autoarr2(KeyValuePair)));
|
||||
for(uint16 i=0;i<HT_HEIGHTS[ht->hein];i++)
|
||||
ht->rows[i]=Autoarr2_create(KeyValuePair,ARR_BC,ARR_BL);
|
||||
newrows[i]=Autoarr2_create(KeyValuePair,ARR_BC,ARR_BL);
|
||||
for(uint16 i=0;i<HT_HEIGHTS[ht->hein-1];i++){
|
||||
Autoarr2(KeyValuePair)* ar=ht->rows+i;
|
||||
for(uint16 k=0;k<Autoarr2_length(ar);k++){
|
||||
uint32 arlen=Autoarr2_length(ar);
|
||||
for(uint16 k=0;k<arlen;k++){
|
||||
KeyValuePair p=Autoarr2_get(ar,k);
|
||||
uint16 newrown=ihash(p.key)%HT_HEIGHTS[ht->hein];
|
||||
Autoarr2(KeyValuePair)* newar=newrows+newrown;
|
||||
Autoarr2_add(newar,p);
|
||||
}
|
||||
Autoarr2_clear(ar);
|
||||
}
|
||||
free(ht->rows);
|
||||
ht->rows=newrows;
|
||||
}
|
||||
|
||||
Autoarr2(KeyValuePair)* getrow(Hashtable* ht, char* key){
|
||||
uint16 rown=ihash(key)%HT_HEIGHTS[ht->hein];
|
||||
//if(rown>=HT_HEIGHTS[ht->hein])
|
||||
// Hashtable_resize(ht);
|
||||
return ht->rows+rown;
|
||||
#include "../tests/tests.h"
|
||||
Autoarr2(KeyValuePair)* getrow(Hashtable* ht, char* key, bool can_expand){
|
||||
Autoarr2(KeyValuePair)* ar=ht->rows+ihash(key)%HT_HEIGHTS[ht->hein];
|
||||
if(can_expand && Autoarr2_length(ar)==Autoarr2_max_length(ar))
|
||||
optime("expand",1,(Hashtable_expand(ht)));
|
||||
ar=ht->rows+ihash(key)%HT_HEIGHTS[ht->hein];
|
||||
return ar;
|
||||
}
|
||||
|
||||
//copies string and value to new KeyValuePair
|
||||
@ -62,7 +69,7 @@ KeyValuePair cpair(char* key, Unitype value){
|
||||
|
||||
|
||||
void Hashtable_add_pair(Hashtable* ht, KeyValuePair p){
|
||||
Autoarr2_add(getrow(ht,p.key),p);
|
||||
Autoarr2_add(getrow(ht,p.key,true),p);
|
||||
}
|
||||
void Hashtable_add(Hashtable* ht, char* key, Unitype u){
|
||||
Hashtable_add_pair(ht,cpair(key,u));
|
||||
@ -70,7 +77,7 @@ void Hashtable_add(Hashtable* ht, char* key, Unitype u){
|
||||
|
||||
//returns null or pointer to value in hashtable
|
||||
Unitype* Hashtable_getptr(Hashtable* ht, char* key){
|
||||
Autoarr2(KeyValuePair)* ar=getrow(ht,key);
|
||||
Autoarr2(KeyValuePair)* ar=getrow(ht,key,false);
|
||||
uint32 arlen=Autoarr2_length(ar);
|
||||
for(uint32 i=0;i<arlen;i++){
|
||||
KeyValuePair* p=Autoarr2_getptr(ar,i);
|
||||
@ -80,7 +87,7 @@ Unitype* Hashtable_getptr(Hashtable* ht, char* key){
|
||||
}
|
||||
|
||||
Unitype Hashtable_get(Hashtable* ht, char* key){
|
||||
Autoarr2(KeyValuePair)* ar=getrow(ht,key);
|
||||
Autoarr2(KeyValuePair)* ar=getrow(ht,key,false);
|
||||
uint32 arlen=Autoarr2_length(ar);
|
||||
for(uint32 i=0;i<arlen;i++){
|
||||
KeyValuePair p=Autoarr2_get(ar,i);
|
||||
|
||||
@ -27,3 +27,12 @@ bool mystrcmp(char* key0, char* key1){
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//multiplies char n times
|
||||
char* mystrmtpl(char c, uint32 n){
|
||||
char* rez=malloc(n+1);
|
||||
rez[n]=0;
|
||||
while(n>0)
|
||||
rez[--n]=c;
|
||||
return rez;
|
||||
}
|
||||
|
||||
@ -2,13 +2,14 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
|
||||
//returns length of string (including \0)
|
||||
uint32 mystrlen(char* str);
|
||||
|
||||
|
||||
//allocates new char[] and copies src there
|
||||
char* mystrcpy(char* src);
|
||||
|
||||
//compares two strings, NullPtr-friendly
|
||||
bool mystrcmp(char* key0, char* key1);
|
||||
|
||||
//multiplies char n times
|
||||
char* mystrmtpl(char c, uint32 n);
|
||||
|
||||
@ -6,8 +6,7 @@
|
||||
int main(){
|
||||
setlocale(LC_ALL, "en-US.Unicode");
|
||||
printf("\e[92mdtsod parser in c language!\e[97m\n");
|
||||
//optime("test_all",1,{test_all();});
|
||||
test_hashtable();
|
||||
optime("test_all",1,{test_all();});
|
||||
printf("\e[0m\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
#include "tests.h"
|
||||
#include "../Hashtable/Hashtable.h"
|
||||
|
||||
void printkvp(KeyValuePair p){
|
||||
printf("{\"%s\", ",p.key);
|
||||
printuni(p.value);
|
||||
printf("}");
|
||||
}
|
||||
|
||||
void print_hashtable(Hashtable* ht){
|
||||
printf("\e[94mHashtable:%lu\n"
|
||||
" hein: %u\n"
|
||||
@ -12,7 +18,30 @@ void print_hashtable(Hashtable* ht){
|
||||
ht->rows);
|
||||
}
|
||||
|
||||
void hashtable_fill(Hashtable* ht){
|
||||
void printrowgraph(Hashtable* ht){
|
||||
printf("\e[94mrow length graph:\n");
|
||||
uint16 lgs_l=1000;
|
||||
uint32 lgs[lgs_l];
|
||||
for(uint32 i=0; i<lgs_l; i++)
|
||||
lgs[i]=0;
|
||||
for(uint16 h=0;h<Hashtable_height(ht);h++){
|
||||
Autoarr2(KeyValuePair)* ar=ht->rows+h;
|
||||
uint32 l=Autoarr2_length(ar);
|
||||
lgs[l]++;
|
||||
}
|
||||
for(uint32 i=0; i<lgs_l; i++)
|
||||
if(lgs[i]>0) {
|
||||
char* str0=mystrmtpl(' ',i>=100?0:(i>=10?1:2));
|
||||
char* str1=mystrmtpl(' ',lgs[i]>=100?0:(lgs[i]>=10?1:2));
|
||||
char* str2=mystrmtpl('#',lgs[i]/100);
|
||||
printf("\e[94m length: \e[96m%u %s \e[94mfrequency: \e[96m%u %s \e[90m%s\n",i,str0,lgs[i],str1,str2);
|
||||
free(str0);
|
||||
free(str1);
|
||||
free(str2);
|
||||
}
|
||||
}
|
||||
|
||||
void fill(Hashtable* ht){
|
||||
char* key=malloc(20);
|
||||
for(uint32 i=0;i<100000;i++){
|
||||
sprintf(key,"key__%u",i);
|
||||
@ -21,7 +50,7 @@ void hashtable_fill(Hashtable* ht){
|
||||
free(key);
|
||||
}
|
||||
|
||||
Unitype hashtable_printval(Hashtable* ht){
|
||||
Unitype gett(Hashtable* ht){
|
||||
char* key=malloc(20);
|
||||
Unitype u;
|
||||
for(uint32 i=0;i<100000;i++){
|
||||
@ -35,19 +64,16 @@ Unitype hashtable_printval(Hashtable* ht){
|
||||
|
||||
|
||||
void test_hashtable(void){
|
||||
/* optime("test_hashtable",1,({
|
||||
optime("test_hashtable",1,({
|
||||
printf("\e[96m-----------[test_hashtable]------------\n");
|
||||
Hashtable* ht=Hashtable_create();
|
||||
printf("\e[92mhashtable created\n");
|
||||
print_hashtable(ht);
|
||||
optime("fill",1,fill(ht));
|
||||
optime("get",1,gett(ht));
|
||||
printrowgraph(ht);
|
||||
print_hashtable(ht);
|
||||
hashtable_fill(ht);
|
||||
printf("\e[92mhashtable filled\n\e[90m");
|
||||
hashtable_printval(ht);
|
||||
Hashtable_free(ht);
|
||||
printf("\n\e[92mhashtable freed\n");
|
||||
})); */
|
||||
printf("\e[96m-----------[test_hashtable]------------\n");
|
||||
Hashtable* ht=Hashtable_create();
|
||||
optime("fill",1,hashtable_fill(ht));
|
||||
optime("get",1,hashtable_printval(ht));
|
||||
Hashtable_free(ht);
|
||||
printf("\e[92mhashtable freed\n");
|
||||
}));
|
||||
}
|
||||
|
||||
@ -17,5 +17,5 @@ void test_hashtable(void);
|
||||
(codeblock);\
|
||||
clock_t stop=clock();\
|
||||
double t=(double)(stop-start)/CLOCKS_PER_SEC/repeats;\
|
||||
printf("\e[93moperation %s took \e[94m%lf \e[93mseconds\n",opname,t);\
|
||||
printf("\e[93moperation \e[94m%s\e[93m took \e[94m%lf \e[93mseconds\n",opname,t);\
|
||||
})
|
||||
|
||||
Loading…
Reference in New Issue
Block a user