hashtable optimized
This commit is contained in:
parent
f9a844447d
commit
756a0494af
@ -3,17 +3,18 @@
|
|||||||
define_Autoarr2(KeyValuePair)
|
define_Autoarr2(KeyValuePair)
|
||||||
|
|
||||||
// amount of rows
|
// 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_BC 2
|
||||||
#define ARR_BL 128
|
#define ARR_BL 8
|
||||||
|
|
||||||
Hashtable* Hashtable_create(){
|
Hashtable* Hashtable_create(){
|
||||||
Hashtable* ht=malloc(sizeof(Hashtable));
|
Hashtable* ht=malloc(sizeof(Hashtable));
|
||||||
//ht->hein=0;//
|
ht->hein=HT_HEIN_MIN;
|
||||||
ht->hein=1;
|
ht->rows=malloc(HT_HEIGHTS[HT_HEIN_MIN]*sizeof(Autoarr2(KeyValuePair)));
|
||||||
ht->rows=malloc(HT_HEIGHTS[ht->hein]*sizeof(Autoarr2(KeyValuePair)));
|
for(uint16 i=0;i<HT_HEIGHTS[HT_HEIN_MIN];i++)
|
||||||
for(uint16 i=0;i<HT_HEIGHTS[ht->hein];i++)
|
|
||||||
ht->rows[i]=Autoarr2_create(KeyValuePair,ARR_BC,ARR_BL);
|
ht->rows[i]=Autoarr2_create(KeyValuePair,ARR_BC,ARR_BL);
|
||||||
return ht;
|
return ht;
|
||||||
}
|
}
|
||||||
@ -32,27 +33,33 @@ void Hashtable_free(Hashtable* ht){
|
|||||||
uint32 Hashtable_height(Hashtable* ht){ return HT_HEIGHTS[ht->hein]; }
|
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)));
|
Autoarr2(KeyValuePair)* newrows=malloc(HT_HEIGHTS[++ht->hein]*sizeof(Autoarr2(KeyValuePair)));
|
||||||
for(uint16 i=0;i<HT_HEIGHTS[ht->hein];i++)
|
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++){
|
for(uint16 i=0;i<HT_HEIGHTS[ht->hein-1];i++){
|
||||||
Autoarr2(KeyValuePair)* ar=ht->rows+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);
|
KeyValuePair p=Autoarr2_get(ar,k);
|
||||||
uint16 newrown=ihash(p.key)%HT_HEIGHTS[ht->hein];
|
uint16 newrown=ihash(p.key)%HT_HEIGHTS[ht->hein];
|
||||||
Autoarr2(KeyValuePair)* newar=newrows+newrown;
|
Autoarr2(KeyValuePair)* newar=newrows+newrown;
|
||||||
Autoarr2_add(newar,p);
|
Autoarr2_add(newar,p);
|
||||||
}
|
}
|
||||||
|
Autoarr2_clear(ar);
|
||||||
}
|
}
|
||||||
|
free(ht->rows);
|
||||||
ht->rows=newrows;
|
ht->rows=newrows;
|
||||||
}
|
}
|
||||||
|
|
||||||
Autoarr2(KeyValuePair)* getrow(Hashtable* ht, char* key){
|
#include "../tests/tests.h"
|
||||||
uint16 rown=ihash(key)%HT_HEIGHTS[ht->hein];
|
Autoarr2(KeyValuePair)* getrow(Hashtable* ht, char* key, bool can_expand){
|
||||||
//if(rown>=HT_HEIGHTS[ht->hein])
|
Autoarr2(KeyValuePair)* ar=ht->rows+ihash(key)%HT_HEIGHTS[ht->hein];
|
||||||
// Hashtable_resize(ht);
|
if(can_expand && Autoarr2_length(ar)==Autoarr2_max_length(ar))
|
||||||
return ht->rows+rown;
|
optime("expand",1,(Hashtable_expand(ht)));
|
||||||
|
ar=ht->rows+ihash(key)%HT_HEIGHTS[ht->hein];
|
||||||
|
return ar;
|
||||||
}
|
}
|
||||||
|
|
||||||
//copies string and value to new KeyValuePair
|
//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){
|
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){
|
void Hashtable_add(Hashtable* ht, char* key, Unitype u){
|
||||||
Hashtable_add_pair(ht,cpair(key,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
|
//returns null or pointer to value in hashtable
|
||||||
Unitype* Hashtable_getptr(Hashtable* ht, char* key){
|
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);
|
uint32 arlen=Autoarr2_length(ar);
|
||||||
for(uint32 i=0;i<arlen;i++){
|
for(uint32 i=0;i<arlen;i++){
|
||||||
KeyValuePair* p=Autoarr2_getptr(ar,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){
|
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);
|
uint32 arlen=Autoarr2_length(ar);
|
||||||
for(uint32 i=0;i<arlen;i++){
|
for(uint32 i=0;i<arlen;i++){
|
||||||
KeyValuePair p=Autoarr2_get(ar,i);
|
KeyValuePair p=Autoarr2_get(ar,i);
|
||||||
|
|||||||
@ -27,3 +27,12 @@ bool mystrcmp(char* key0, char* key1){
|
|||||||
}
|
}
|
||||||
return 1;
|
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"
|
#include "types.h"
|
||||||
|
|
||||||
|
|
||||||
//returns length of string (including \0)
|
//returns length of string (including \0)
|
||||||
uint32 mystrlen(char* str);
|
uint32 mystrlen(char* str);
|
||||||
|
|
||||||
|
|
||||||
//allocates new char[] and copies src there
|
//allocates new char[] and copies src there
|
||||||
char* mystrcpy(char* src);
|
char* mystrcpy(char* src);
|
||||||
|
|
||||||
//compares two strings, NullPtr-friendly
|
//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);
|
||||||
|
|||||||
@ -6,8 +6,7 @@
|
|||||||
int main(){
|
int main(){
|
||||||
setlocale(LC_ALL, "en-US.Unicode");
|
setlocale(LC_ALL, "en-US.Unicode");
|
||||||
printf("\e[92mdtsod parser in c language!\e[97m\n");
|
printf("\e[92mdtsod parser in c language!\e[97m\n");
|
||||||
//optime("test_all",1,{test_all();});
|
optime("test_all",1,{test_all();});
|
||||||
test_hashtable();
|
|
||||||
printf("\e[0m\n");
|
printf("\e[0m\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,12 @@
|
|||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
#include "../Hashtable/Hashtable.h"
|
#include "../Hashtable/Hashtable.h"
|
||||||
|
|
||||||
|
void printkvp(KeyValuePair p){
|
||||||
|
printf("{\"%s\", ",p.key);
|
||||||
|
printuni(p.value);
|
||||||
|
printf("}");
|
||||||
|
}
|
||||||
|
|
||||||
void print_hashtable(Hashtable* ht){
|
void print_hashtable(Hashtable* ht){
|
||||||
printf("\e[94mHashtable:%lu\n"
|
printf("\e[94mHashtable:%lu\n"
|
||||||
" hein: %u\n"
|
" hein: %u\n"
|
||||||
@ -12,7 +18,30 @@ void print_hashtable(Hashtable* ht){
|
|||||||
ht->rows);
|
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);
|
char* key=malloc(20);
|
||||||
for(uint32 i=0;i<100000;i++){
|
for(uint32 i=0;i<100000;i++){
|
||||||
sprintf(key,"key__%u",i);
|
sprintf(key,"key__%u",i);
|
||||||
@ -21,7 +50,7 @@ void hashtable_fill(Hashtable* ht){
|
|||||||
free(key);
|
free(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
Unitype hashtable_printval(Hashtable* ht){
|
Unitype gett(Hashtable* ht){
|
||||||
char* key=malloc(20);
|
char* key=malloc(20);
|
||||||
Unitype u;
|
Unitype u;
|
||||||
for(uint32 i=0;i<100000;i++){
|
for(uint32 i=0;i<100000;i++){
|
||||||
@ -35,19 +64,16 @@ Unitype hashtable_printval(Hashtable* ht){
|
|||||||
|
|
||||||
|
|
||||||
void test_hashtable(void){
|
void test_hashtable(void){
|
||||||
/* optime("test_hashtable",1,({
|
optime("test_hashtable",1,({
|
||||||
printf("\e[96m-----------[test_hashtable]------------\n");
|
printf("\e[96m-----------[test_hashtable]------------\n");
|
||||||
Hashtable* ht=Hashtable_create();
|
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);
|
print_hashtable(ht);
|
||||||
hashtable_fill(ht);
|
|
||||||
printf("\e[92mhashtable filled\n\e[90m");
|
|
||||||
hashtable_printval(ht);
|
|
||||||
Hashtable_free(ht);
|
Hashtable_free(ht);
|
||||||
printf("\n\e[92mhashtable freed\n");
|
printf("\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);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,5 +17,5 @@ void test_hashtable(void);
|
|||||||
(codeblock);\
|
(codeblock);\
|
||||||
clock_t stop=clock();\
|
clock_t stop=clock();\
|
||||||
double t=(double)(stop-start)/CLOCKS_PER_SEC/repeats;\
|
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