#include "Hashtable.h" // amount of rows static const uint16 HT_HEIGHTS[]={17,61,257,1021,4099,16381,65521}; #define HT_HEIN_MIN 0 #define HT_HEIN_MAX 6 #define ARR_BC 2 #define ARR_BL 8 Hashtable* Hashtable_create(){ Hashtable* ht=malloc(sizeof(Hashtable)); ht->hein=HT_HEIN_MIN; ht->rows=malloc(HT_HEIGHTS[HT_HEIN_MIN]*sizeof(Autoarr(KVPair)*)); for(uint16 i=0;irows[i]=Autoarr_create(KVPair,ARR_BC,ARR_BL); return ht; } void Hashtable_free(Hashtable* ht){ for(uint16 i=0;ihein];i++) Autoarr_free_KVPair(ht->rows[i]); free(ht->rows); free(ht); } uint16 Hashtable_height(Hashtable* ht) { return HT_HEIGHTS[ht->hein]; } void Hashtable_expand(Hashtable* ht){ if(ht->hein>=HT_HEIN_MAX) throw(ERR_MAXLENGTH); Autoarr(KVPair)** newrows=malloc(HT_HEIGHTS[++ht->hein]*sizeof(Autoarr(KVPair))); for(uint16 i=0;ihein];i++) newrows[i]=Autoarr_create(KVPair,ARR_BC,ARR_BL); for(uint16 i=0;ihein-1];i++){ Autoarr(KVPair)* ar=ht->rows[i]; uint32 arlen=Autoarr_length(ar); for(uint16 k=0;khein]; Autoarr(KVPair)* newar=newrows[newrown]; Autoarr_add(newar,p); } // it is a feature, not a bug // no need to free kvpair keys and values, they just moved to new autoarrs Autoarr_free(ar); } free(ht->rows); ht->rows=newrows; } Autoarr(KVPair)* getrow(Hashtable* ht, char* key, bool can_expand){ Autoarr(KVPair)* ar=ht->rows[ihash(key)%HT_HEIGHTS[ht->hein]]; if(can_expand && Autoarr_length(ar)==Autoarr_max_length(ar)) optime("expand",1,(Hashtable_expand(ht))); ar=ht->rows[ihash(key)%HT_HEIGHTS[ht->hein]]; return ar; } void Hashtable_add_pair(Hashtable* ht, KVPair p){ Autoarr_add(getrow(ht,p.key,true),p); } void Hashtable_add(Hashtable* ht, char* key, Unitype u){ Hashtable_add_pair(ht,KVPair(key,u)); } // returns null or pointer to value in hashtable Unitype* Hashtable_getptr(Hashtable* ht, char* key){ Autoarr(KVPair)* ar=getrow(ht,key,false); uint32 arlen=Autoarr_length(ar); for(uint32 i=0;ikey)) return &p->value; } return NULL; } Unitype Hashtable_get(Hashtable* ht, char* key){ Autoarr(KVPair)* ar=getrow(ht,key,false); uint32 arlen=Autoarr_length(ar); for(uint32 i=0;i