Hashtable

This commit is contained in:
timerix 2023-10-27 14:21:29 +06:00
parent b6088845d9
commit 885ef7fea6
7 changed files with 43 additions and 112 deletions

View File

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

View File

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

View File

@ -7,51 +7,47 @@ 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)*));
allocator_ptr internal_al = InternalAllocator_getPtr(ht);
for(u16 i=0; i<HT_HEIGHTS[HT_HEIN_MIN]; i++)
ht->rows[i]=Autoarr_construct(KVPair,ARR_BC,ARR_BL);
return ht;
Autoarr_construct(&ht->rows[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;i<HT_HEIGHTS[ht->hein];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;i<HT_HEIGHTS[ht->hein];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;i<HT_HEIGHTS[ht->hein-1];i++){
Autoarr(KVPair)* ar=ht->rows[i];
Autoarr(KVPair)* ar=&ht->rows[i];
u32 arlen=Autoarr_length(ar);
for(u32 k=0;k<arlen;k++){
KVPair p=Autoarr_get(ar,k);
u16 newrown=hashs(hash_sdbm32, p.key)%HT_HEIGHTS[ht->hein];
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);
@ -60,10 +56,10 @@ void Hashtable_expand(Hashtable* ht){
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;i<arlen;i++){
KVPair* p=Autoarr_getPtr(ar,i);
if(cptr_equals(key,p->key)) 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;i<arlen;i++){
KVPair p=Autoarr_get(ar,i);
if(cptr_equals(key,p.key)) return p.value;
if(cptr_equals(key,p.key))
return p.value;
}
return UniNull;
}

View File

@ -9,17 +9,15 @@ extern "C" {
#include "KeyValuePair.h"
STRUCT(Hashtable,
InternalAllocator_declare(LinearAllocator);
u8 hein; // height=HT_HEIGHTS[hein]
Autoarr(KVPair)** rows; // Autoarr[height]
Autoarr(KVPair)* rows; // Autoarr[height]
)
Hashtable* Hashtable_create();
void Hashtable_construct(Hashtable* ht, allocator_ptr external_al);
void Hashtable_destruct(Hashtable* ht);
void __Hashtable_destruct(void* ht);
// amount of rows
u16 Hashtable_height(Hashtable* ht);
// don't add pairs with the same keys,
// or something weird will happen
// if not sure, use Hashtable_addOrSet()
@ -36,11 +34,13 @@ Unitype* Hashtable_getPtr(Hashtable* ht, char* key);
Unitype Hashtable_get(Hashtable* ht, char* key);
bool Hashtable_tryGet(Hashtable* ht, char* key, Unitype* output);
u16 __Hashtable_height(Hashtable* ht);
#define Hashtable_foreach(HT, EL, codeblock...) { \
u16 hmax=Hashtable_height(HT); \
u16 hmax=__Hashtable_height(HT); \
for(u16 h=0; h<hmax; h++){ \
Autoarr(KVPair)* AR=HT->rows[h]; \
Autoarr_foreach(AR, EL, codeblock); \
Autoarr(KVPair)* row=&HT->rows[h]; \
Autoarr_foreach(row, EL, codeblock); \
} \
}

View File

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

View File

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

View File

@ -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; i<lgs_l; i++)
lgs[i]=0;
for(u16 h=0;h<Hashtable_height(ht);h++){
Autoarr(KVPair)* ar=ht->rows[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));