Hashtable
This commit is contained in:
parent
b6088845d9
commit
885ef7fea6
@ -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){
|
||||
|
||||
@ -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
|
||||
@ -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;i<HT_HEIGHTS[HT_HEIN_MIN];i++)
|
||||
ht->rows[i]=Autoarr_construct(KVPair,ARR_BC,ARR_BL);
|
||||
return ht;
|
||||
allocator_ptr internal_al = InternalAllocator_getPtr(ht);
|
||||
for(u16 i=0; i<HT_HEIGHTS[HT_HEIN_MIN]; i++)
|
||||
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);
|
||||
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;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;
|
||||
}
|
||||
|
||||
@ -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); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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));
|
||||
|
||||
Loading…
Reference in New Issue
Block a user