diff --git a/DtsodC/src/Hashtable/Hashtable.c b/DtsodC/src/Hashtable/Hashtable.c index 775bb85..9d14d09 100644 --- a/DtsodC/src/Hashtable/Hashtable.c +++ b/DtsodC/src/Hashtable/Hashtable.c @@ -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;ihein];i++) + ht->hein=HT_HEIN_MIN; + ht->rows=malloc(HT_HEIGHTS[HT_HEIN_MIN]*sizeof(Autoarr2(KeyValuePair))); + for(uint16 i=0;irows[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;ihein];i++) - ht->rows[i]=Autoarr2_create(KeyValuePair,ARR_BC,ARR_BL); + newrows[i]=Autoarr2_create(KeyValuePair,ARR_BC,ARR_BL); for(uint16 i=0;ihein-1];i++){ Autoarr2(KeyValuePair)* ar=ht->rows+i; - for(uint16 k=0;khein]; 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;i0) + rez[--n]=c; + return rez; +} diff --git a/DtsodC/src/base/mystr.h b/DtsodC/src/base/mystr.h index b1fe233..5e9e150 100644 --- a/DtsodC/src/base/mystr.h +++ b/DtsodC/src/base/mystr.h @@ -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); \ No newline at end of file +bool mystrcmp(char* key0, char* key1); + +//multiplies char n times +char* mystrmtpl(char c, uint32 n); diff --git a/DtsodC/src/main.c b/DtsodC/src/main.c index 4c11d95..8bbccd1 100644 --- a/DtsodC/src/main.c +++ b/DtsodC/src/main.c @@ -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; } diff --git a/DtsodC/src/tests/test_hashtable.c b/DtsodC/src/tests/test_hashtable.c index eaaabf9..569d143 100644 --- a/DtsodC/src/tests/test_hashtable.c +++ b/DtsodC/src/tests/test_hashtable.c @@ -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; irows+h; + uint32 l=Autoarr2_length(ar); + lgs[l]++; + } + for(uint32 i=0; i0) { + 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"); + })); } diff --git a/DtsodC/src/tests/tests.h b/DtsodC/src/tests/tests.h index 3248c4a..4b0268f 100644 --- a/DtsodC/src/tests/tests.h +++ b/DtsodC/src/tests/tests.h @@ -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);\ })