diff --git a/src/DtsodParser/DtsodV24_deserialize.c b/src/DtsodParser/DtsodV24_deserialize.c index 87a9faa..e01f7d0 100644 --- a/src/DtsodParser/DtsodV24_deserialize.c +++ b/src/DtsodParser/DtsodV24_deserialize.c @@ -295,7 +295,9 @@ Maybe __deserialize(char** _text, bool _calledRecursively, allocator_ptr _tmp_al .sh_tmp_al=_tmp_al }; DeserializeSharedData* shared=&_shared; - Hashtable* dict=Hashtable_create(); + Hashtable _dict; + Hashtable* dict = &_dict; + Hashtable_construct(dict, _tmp_al); text--; while(true){ diff --git a/src/DtsodParser/DtsodV24_exported.c b/src/DtsodParser/DtsodV24_exported.c deleted file mode 100644 index 1544d85..0000000 --- a/src/DtsodParser/DtsodV24_exported.c +++ /dev/null @@ -1,62 +0,0 @@ -// -// I planned to export functions from DtsodV24.h, -// but C# P/Invoke can't get returned values for some reason. -// Following functions return values by pointer, which looks in C# like out parameter -// - -#if __cplusplus -extern "C" { -#endif - -#include "DtsodV24.h" - -// parses text to binary values -EXPORT void CALL kerep_DtsodV24_deserialize(char* text, Hashtable** output, char** errmsg){ - Maybe r=DtsodV24_deserialize(text); - *errmsg=r.errmsg; - *output=r.value.VoidPtr; -} - -// creates text representation of dtsod -EXPORT void CALL kerep_DtsodV24_serialize(Hashtable* dtsod, char** output, char** errmsg){ - Maybe r=DtsodV24_serialize(dtsod); - *errmsg=r.errmsg; - *output=r.value.VoidPtr; -} - -// returns value or UniNull if key not found -EXPORT void CALL kerep_DtsodV24_get(Hashtable* dtsod, char* key, Unitype* output){ - *output=DtsodV24_get(dtsod, key); -} - -// adds or sets the value -EXPORT void CALL kerep_DtsodV24_addOrSet(Hashtable* dtsod, char* key, Unitype value){ - DtsodV24_addOrSet(dtsod, key, value); -} - -// checks for dtsod contains value or dont -EXPORT void CALL kerep_DtsodV24_contains(Hashtable* dtsod, char* key, bool* output){ - *output=DtsodV24_contains(dtsod, key); -} - -// replaces value with UniNull if key exists in dtsod -EXPORT void CALL kerep_DtsodV24_remove(Hashtable* dtsod, char* key, bool* output){ - *output=DtsodV24_remove(dtsod, key); -} - -// replaces value with UniNull if key exists in dtsod -EXPORT void CALL kerep_DtsodV24_destruct(Hashtable* dtsod){ - DtsodV24_destruct(dtsod); -} - -EXPORT void CALL kerep_DtsodV24_height(Hashtable* dtsod, u16* heigth){ - *heigth=Hashtable_height(dtsod); -} - -EXPORT void CALL kerep_DtsodV24_getrow(Hashtable* dtsod, u16 h, Autoarr_KVPair** row){ - *row=dtsod->rows[h]; -} - -#if __cplusplus -} -#endif diff --git a/src/Hashtable/Hashtable.c b/src/Hashtable/Hashtable.c index 1e9fe5e..6f21688 100644 --- a/src/Hashtable/Hashtable.c +++ b/src/Hashtable/Hashtable.c @@ -7,63 +7,59 @@ static const u16 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 +#define ARR_SIZE_MAX 16 -Hashtable* Hashtable_create(){ - Hashtable* ht=malloc(sizeof(Hashtable)); +void Hashtable_construct(Hashtable* ht, allocator_ptr external_al){ + InternalAllocator_setExternalOrConstruct(ht, external_al, LinearAllocator, 1024); ht->hein=HT_HEIN_MIN; ht->rows=malloc(HT_HEIGHTS[HT_HEIN_MIN]*sizeof(Autoarr(KVPair)*)); - for(u16 i=0;irows[i]=Autoarr_construct(KVPair,ARR_BC,ARR_BL); - return ht; + allocator_ptr internal_al = InternalAllocator_getPtr(ht); + for(u16 i=0; irows[i], KVPair, 16, internal_al); } +u16 __Hashtable_height(Hashtable* ht) { return HT_HEIGHTS[ht->hein]; } + void __Hashtable_destruct(void* _ht){ Hashtable* ht=_ht; for(u16 i=0;ihein];i++) - Autoarr_destruct(ht->rows[i], true); - free(ht->rows); + Autoarr_destruct(&ht->rows[i]); + allocator_free(InternalAllocator_getPtr(ht), ht->rows); + InternalAllocator_destructIfInternal(LinearAllocator, ht); } void Hashtable_destruct(Hashtable* ht){ __Hashtable_destruct(ht); - free(ht); } -u16 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)*)); + Autoarr(KVPair)* newrows=malloc(HT_HEIGHTS[++ht->hein]*sizeof(Autoarr(KVPair)*)); for(u16 i=0;ihein];i++) - newrows[i]=Autoarr_construct(KVPair,ARR_BC,ARR_BL); + Autoarr_construct(&newrows[i], KVPair, ARR_SIZE_MAX, InternalAllocator_getPtr(ht)); for(u16 i=0;ihein-1];i++){ - Autoarr(KVPair)* ar=ht->rows[i]; + Autoarr(KVPair)* ar=&ht->rows[i]; u32 arlen=Autoarr_length(ar); for(u32 k=0;khein]; - Autoarr(KVPair)* newar=newrows[newrown]; + Autoarr(KVPair)* newar=&newrows[newrown]; Autoarr_add(newar,p); } - // there is no need to free array values, because they are copied into new array - // so dont replace this incorrect auto-generated function - Autoarr_destructWithoutMembers(ar, true); + Autoarr_destruct(ar); } free(ht->rows); - ht->rows=newrows; + ht->rows = newrows; } Autoarr(KVPair)* getrow(Hashtable* ht, char* key, bool can_expand){ u32 hash=hashs(hash_sdbm32, key); - Autoarr(KVPair)* ar=ht->rows[hash%HT_HEIGHTS[ht->hein]]; - if(can_expand && Autoarr_length(ar)==Autoarr_max_length(ar)) + Autoarr(KVPair)* ar=&ht->rows[hash%HT_HEIGHTS[ht->hein]]; + if(can_expand && Autoarr_length(ar) == ARR_SIZE_MAX) Hashtable_expand(ht); - ar=ht->rows[hash%HT_HEIGHTS[ht->hein]]; + ar=&ht->rows[hash%HT_HEIGHTS[ht->hein]]; return ar; } @@ -86,7 +82,8 @@ Unitype* Hashtable_getPtr(Hashtable* ht, char* key){ u32 arlen=Autoarr_length(ar); for(u32 i=0;ikey)) return &p->value; + if(cptr_equals(key,p->key)) + return &p->value; } return NULL; } @@ -96,7 +93,8 @@ Unitype Hashtable_get(Hashtable* ht, char* key){ u32 arlen=Autoarr_length(ar); for(u32 i=0;irows[h]; \ - Autoarr_foreach(AR, EL, codeblock); \ + Autoarr(KVPair)* row=&HT->rows[h]; \ + Autoarr_foreach(row, EL, codeblock); \ } \ } diff --git a/src/Hashtable/KeyValuePair.c b/src/Hashtable/KeyValuePair.c index a6ca36e..03f2895 100644 --- a/src/Hashtable/KeyValuePair.c +++ b/src/Hashtable/KeyValuePair.c @@ -1,15 +1,8 @@ #include "KeyValuePair.h" -kt_define(KVPair, __KVPair_destruct, NULL); +kt_define(KVPair, NULL, NULL); -Autoarr_define(KVPair, false) - -// proper way to clean a KVP -void KVPair_destruct(KVPair p){ - // free(p.key); - Unitype_destruct(&p.value); -} -void __KVPair_destruct(void* p){ KVPair_destruct(*(KVPair*)p); } +Autoarr_define(KVPair) void printkvp(KVPair p){ kprintf("{\"%s\", ",p.key); diff --git a/src/Hashtable/KeyValuePair.h b/src/Hashtable/KeyValuePair.h index 815bdb1..0dd31c0 100644 --- a/src/Hashtable/KeyValuePair.h +++ b/src/Hashtable/KeyValuePair.h @@ -14,8 +14,6 @@ STRUCT(KVPair, Autoarr_declare(KVPair) -// proper way to clean a KVP -void KVPair_destruct(KVPair p); void __KVPair_destruct(void* p); void printkvp(KVPair p); diff --git a/tests/test_hashtable.c b/tests/test_hashtable.c index ddb671f..ba2bfec 100644 --- a/tests/test_hashtable.c +++ b/tests/test_hashtable.c @@ -8,7 +8,7 @@ void print_hashtable(Hashtable* ht){ " rows: %p\n", sizeof(Hashtable), ht->hein, - Hashtable_height(ht), + __Hashtable_height(ht), ht->rows); } @@ -18,8 +18,8 @@ void printrowgraph(allocator_ptr al, Hashtable* ht){ u32 lgs[lgs_l]; for(u32 i=0; irows[h]; + for(u16 h=0;h<__Hashtable_height(ht);h++){ + Autoarr(KVPair)* ar=&ht->rows[h]; u32 l=Autoarr_length(ar); lgs[l]++; } @@ -63,7 +63,9 @@ void test_hashtable(){ StackingAllocator _al; allocator_ptr al=(allocator_ptr)&_al; StackingAllocator_construct(&_al, 4096); - Hashtable* ht=Hashtable_create(); + Hashtable _ht; + Hashtable* ht=&_ht; + Hashtable_construct(ht, al); kprintf("\e[92mhashtable created\n"); print_hashtable(ht); optime("fill",1,fill(al, ht));