Allow hashtable to grow
Some checks are pending
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Waiting to run

This commit is contained in:
Vladimir Dubrovin 2026-04-18 17:24:01 +03:00
parent 45796f66c7
commit a3729354b8
2 changed files with 52 additions and 20 deletions

View File

@ -25,6 +25,7 @@ void destroyhashtable(struct hashtable *ht){
int inithashtable(struct hashtable *ht, unsigned nhashsize){ int inithashtable(struct hashtable *ht, unsigned nhashsize){
unsigned i; unsigned i;
unsigned tablesize, hashsize;
clock_t c; clock_t c;
@ -40,7 +41,8 @@ int inithashtable(struct hashtable *ht, unsigned nhashsize){
#endif #endif
c = clock(); c = clock();
if(nhashsize<4) return 1; hashsize = tablesize = (nhashsize >> 2);
if(tablesize < 2) return 1;
pthread_mutex_lock(&hash_mutex); pthread_mutex_lock(&hash_mutex);
if(ht->ihashtable){ if(ht->ihashtable){
myfree(ht->ihashtable); myfree(ht->ihashtable);
@ -51,18 +53,20 @@ int inithashtable(struct hashtable *ht, unsigned nhashsize){
ht->hashvalues = NULL; ht->hashvalues = NULL;
} }
ht->hashsize = 0; ht->hashsize = 0;
if(!(ht->ihashtable = myalloc((nhashsize>>2) * sizeof(int)))){ ht->tablesize = 0;
if(!(ht->ihashtable = myalloc(tablesize * sizeof(uint32_t)))){
pthread_mutex_unlock(&hash_mutex); pthread_mutex_unlock(&hash_mutex);
return 2; return 2;
} }
if(!(ht->hashvalues = myalloc(nhashsize * (sizeof(struct hashentry) + (ht->recsize-4))))){ if(!(ht->hashvalues = myalloc(hashsize * (sizeof(struct hashentry) + (ht->recsize-4))))){
myfree(ht->ihashtable); myfree(ht->ihashtable);
ht->ihashtable = NULL; ht->ihashtable = NULL;
pthread_mutex_unlock(&hash_mutex); pthread_mutex_unlock(&hash_mutex);
return 3; return 3;
} }
ht->hashsize = nhashsize; ht->hashsize = hashsize;
ht->tablesize = (nhashsize>>2); ht->tablesize = tablesize;
ht->growlimit = nhashsize;
ht->rnd[0] = myrand(&tb, sizeof(tb)); ht->rnd[0] = myrand(&tb, sizeof(tb));
ht->rnd[1] = myrand(ht->ihashtable, sizeof(ht->ihashtable)); ht->rnd[1] = myrand(ht->ihashtable, sizeof(ht->ihashtable));
ht->rnd[2] = myrand(&c, sizeof(c)); ht->rnd[2] = myrand(&c, sizeof(c));
@ -78,11 +82,37 @@ int inithashtable(struct hashtable *ht, unsigned nhashsize){
return 0; return 0;
} }
static void hashgrow(struct hashtable *ht){
unsigned newsize = (ht->hashsize + (ht->hashsize >> 1));
unsigned i;
void * newvalues;
if(!ht->tablesize || !ht->hashsize) return;
if(ht->hashsize >= ht->growlimit) return;
if(ht->hashsize / ht->tablesize > 100) return;
if(newsize > ht->growlimit) newsize = ht->growlimit;
newvalues = myrealloc(ht->hashvalues, newsize * (sizeof(struct hashentry) + ht->recsize - 4));
if(!newvalues) return;
memset(ht->hashvalues + (ht->hashsize * (sizeof(struct hashentry) + ht->recsize - 4)), 0, (newsize - ht->hashsize) * (sizeof(struct hashentry) + ht->recsize - 4));
for(i = ht->hashsize + 1; i < newsize; i++) {
hvalue(ht,i)->inext = i+1;
}
hvalue(ht,newsize)->inext = ht->ihashempty;
ht->ihashempty = ht->hashsize + 1;
ht->hashsize = newsize;
}
/*
static void hashcompact(struct hashtable *ht){ static void hashcompact(struct hashtable *ht){
int i; int i;
uint32_t he, *hep; uint32_t he, *hep;
if((conf.time - ht->compacted) < 60 || !ht->tablesize || !ht->hashsize || ht->hashsize/ht->tablesize >= 4 ) return; if((conf.time - ht->compacted) < 60 || !ht->tablesize || !ht->hashsize || ht->ihashempty) return;
if(ht->grow && ht->hashsize/ht->tablesize < 100){
hashgrow(ht);
if(ht->ihashempty) return;
}
if(ht->hashsize/ht->tablesize < 4){
for(i = 0; i < ht->tablesize; i++){ for(i = 0; i < ht->tablesize; i++){
for(hep = ht->ihashtable + i; (he = *hep) != 0; ){ for(hep = ht->ihashtable + i; (he = *hep) != 0; ){
if(hvalue(ht,he)->expires < conf.time ) { if(hvalue(ht,he)->expires < conf.time ) {
@ -95,7 +125,10 @@ static void hashcompact(struct hashtable *ht){
} }
} }
ht->compacted = conf.time; ht->compacted = conf.time;
if(ht->ihashempty) return;
} }
}
*/
void hashadd(struct hashtable *ht, const void* name, const void* value, time_t expires){ void hashadd(struct hashtable *ht, const void* name, const void* value, time_t expires){
uint32_t hen, he; uint32_t hen, he;
@ -105,7 +138,7 @@ void hashadd(struct hashtable *ht, const void* name, const void* value, time_t e
pthread_mutex_lock(&hash_mutex); pthread_mutex_lock(&hash_mutex);
if(!ht->ihashempty){ if(!ht->ihashempty){
hashcompact(ht); hashgrow(ht);
} }
if(!ht||!value||!name||!ht->ihashtable||!ht->ihashempty) { if(!ht||!value||!name||!ht->ihashtable||!ht->ihashempty) {
pthread_mutex_unlock(&hash_mutex); pthread_mutex_unlock(&hash_mutex);

View File

@ -771,8 +771,7 @@ struct hashtable {
uint8_t * hashvalues; uint8_t * hashvalues;
uint32_t ihashempty; uint32_t ihashempty;
void (*index2hash)(const void *index, unsigned char *hash, const unsigned char *rnd); void (*index2hash)(const void *index, unsigned char *hash, const unsigned char *rnd);
int grow; unsigned growlimit;
time_t compacted;
int tablesize; int tablesize;
}; };