hashtable optimized

This commit is contained in:
Timerix22 2022-02-23 20:19:05 +03:00
parent f9a844447d
commit 756a0494af
6 changed files with 79 additions and 37 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
bool mystrcmp(char* key0, char* key1);
//multiplies char n times
char* mystrmtpl(char c, uint32 n);

View File

@ -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;
}

View File

@ -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");
}));
}

View File

@ -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);\
})