mirror of
https://github.com/3proxy/3proxy.git
synced 2026-04-28 15:10:12 +08:00
Allow different hash lengths; fix bug on hashtable grow
This commit is contained in:
parent
ee00956b74
commit
3957210609
31
src/hash.c
31
src/hash.c
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
|
|
||||||
struct hashentry {
|
struct hashentry {
|
||||||
uint8_t hash[HASH_SIZE];
|
|
||||||
time_t expires;
|
time_t expires;
|
||||||
uint32_t inext;
|
uint32_t inext;
|
||||||
char value[4];
|
char value[4];
|
||||||
@ -24,12 +23,17 @@ void destroyhashtable(struct hashtable *ht){
|
|||||||
myfree(ht->hashvalues);
|
myfree(ht->hashvalues);
|
||||||
ht->hashvalues = NULL;
|
ht->hashvalues = NULL;
|
||||||
}
|
}
|
||||||
|
if(ht->hashhashvalues){
|
||||||
|
myfree(ht->hashvalues);
|
||||||
|
ht->hashvalues = NULL;
|
||||||
|
}
|
||||||
ht->poolsize = 0;
|
ht->poolsize = 0;
|
||||||
ht->tablesize = 0;
|
ht->tablesize = 0;
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define hvalue(ht,I) ((struct hashentry *)(ht->hashvalues + (I-1)*(sizeof(struct hashentry) + ht->recsize - 4)))
|
#define hvalue(ht,I) ((struct hashentry *)(ht->hashvalues + (I-1)*(sizeof(struct hashentry) + ht->recsize - 4)))
|
||||||
|
#define hhash(ht,I) ((ht->hashhashvalues + (I-1)*(ht->hash_size)))
|
||||||
|
|
||||||
int inithashtable(struct hashtable *ht, unsigned npoolsize){
|
int inithashtable(struct hashtable *ht, unsigned npoolsize){
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@ -59,15 +63,20 @@ int inithashtable(struct hashtable *ht, unsigned npoolsize){
|
|||||||
myfree(ht->hashvalues);
|
myfree(ht->hashvalues);
|
||||||
ht->hashvalues = NULL;
|
ht->hashvalues = NULL;
|
||||||
}
|
}
|
||||||
|
if(ht->hashhashvalues){
|
||||||
|
myfree(ht->hashvalues);
|
||||||
|
ht->hashvalues = NULL;
|
||||||
|
}
|
||||||
ht->poolsize = 0;
|
ht->poolsize = 0;
|
||||||
ht->tablesize = 0;
|
ht->tablesize = 0;
|
||||||
if(!(ht->ihashtable = myalloc(tablesize * sizeof(uint32_t)))){
|
if(!(ht->ihashtable = myalloc(tablesize * sizeof(uint32_t)))
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|| !(ht->hashvalues = myalloc(poolsize * (sizeof(struct hashentry) + (ht->recsize-4))))
|
||||||
return 2;
|
|| !(ht->hashhashvalues = myalloc(poolsize * ht->hash_size))
|
||||||
}
|
){
|
||||||
if(!(ht->hashvalues = myalloc(poolsize * (sizeof(struct hashentry) + (ht->recsize-4))))){
|
|
||||||
myfree(ht->ihashtable);
|
myfree(ht->ihashtable);
|
||||||
ht->ihashtable = NULL;
|
ht->ihashtable = NULL;
|
||||||
|
myfree(ht->hashvalues);
|
||||||
|
ht->hashvalues = NULL;
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
@ -117,6 +126,10 @@ static void hashgrow(struct hashtable *ht){
|
|||||||
if(newsize > ht->growlimit) newsize = ht->growlimit;
|
if(newsize > ht->growlimit) newsize = ht->growlimit;
|
||||||
newvalues = myrealloc(ht->hashvalues, newsize * (sizeof(struct hashentry) + ht->recsize - 4));
|
newvalues = myrealloc(ht->hashvalues, newsize * (sizeof(struct hashentry) + ht->recsize - 4));
|
||||||
if(!newvalues) return;
|
if(!newvalues) return;
|
||||||
|
ht->hashvalues = newvalues;
|
||||||
|
newvalues = myrealloc(ht->hashhashvalues, newsize * ht->hash_size);
|
||||||
|
if(!newvalues) return;
|
||||||
|
ht->hashhashvalues = newvalues;
|
||||||
memset(ht->hashvalues + (ht->poolsize * (sizeof(struct hashentry) + ht->recsize - 4)), 0, (newsize - ht->poolsize) * (sizeof(struct hashentry) + ht->recsize - 4));
|
memset(ht->hashvalues + (ht->poolsize * (sizeof(struct hashentry) + ht->recsize - 4)), 0, (newsize - ht->poolsize) * (sizeof(struct hashentry) + ht->recsize - 4));
|
||||||
for(i = ht->poolsize + 1; i < newsize; i++) {
|
for(i = ht->poolsize + 1; i < newsize; i++) {
|
||||||
hvalue(ht,i)->inext = i+1;
|
hvalue(ht,i)->inext = i+1;
|
||||||
@ -145,7 +158,7 @@ void hashadd(struct hashtable *ht, const void* name, const void* value, time_t e
|
|||||||
index = hashindex(ht, hash);
|
index = hashindex(ht, hash);
|
||||||
|
|
||||||
for(hep = ht->ihashtable + index; (he = *hep)!=0; ){
|
for(hep = ht->ihashtable + index; (he = *hep)!=0; ){
|
||||||
if(hvalue(ht,he)->expires < conf.time || !memcmp(hash, hvalue(ht,he)->hash, ht->hash_size)) {
|
if(hvalue(ht,he)->expires < conf.time || !memcmp(hash, hhash(ht,he), ht->hash_size)) {
|
||||||
(*hep) = hvalue(ht,he)->inext;
|
(*hep) = hvalue(ht,he)->inext;
|
||||||
hvalue(ht,he)->expires = 0;
|
hvalue(ht,he)->expires = 0;
|
||||||
hvalue(ht,he)->inext = ht->ihashempty;
|
hvalue(ht,he)->inext = ht->ihashempty;
|
||||||
@ -171,7 +184,7 @@ void hashadd(struct hashtable *ht, const void* name, const void* value, time_t e
|
|||||||
hen = last;
|
hen = last;
|
||||||
}
|
}
|
||||||
if(hen){
|
if(hen){
|
||||||
memcpy(hvalue(ht,hen)->hash, hash, ht->hash_size);
|
memcpy(hhash(ht,hen), hash, ht->hash_size);
|
||||||
memcpy(hvalue(ht,hen)->value, value, ht->recsize);
|
memcpy(hvalue(ht,hen)->value, value, ht->recsize);
|
||||||
hvalue(ht,hen)->expires = expires;
|
hvalue(ht,hen)->expires = expires;
|
||||||
}
|
}
|
||||||
@ -198,7 +211,7 @@ int hashresolv(struct hashtable *ht, const void* name, void* value, uint32_t *tt
|
|||||||
hvalue(ht,he)->inext = ht->ihashempty;
|
hvalue(ht,he)->inext = ht->ihashempty;
|
||||||
ht->ihashempty = he;
|
ht->ihashempty = he;
|
||||||
}
|
}
|
||||||
else if(!memcmp(hash, hvalue(ht,he)->hash, ht->hash_size)){
|
else if(!memcmp(hash, hhash(ht,he), ht->hash_size)){
|
||||||
if(ttl) *ttl = (uint32_t)(hvalue(ht,he)->expires - conf.time);
|
if(ttl) *ttl = (uint32_t)(hvalue(ht,he)->expires - conf.time);
|
||||||
memcpy(value, hvalue(ht,he)->value, ht->recsize);
|
memcpy(value, hvalue(ht,he)->value, ht->recsize);
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
|||||||
@ -765,7 +765,9 @@ struct hashtable {
|
|||||||
void (*index2hash)(const void *index, unsigned char *hash);
|
void (*index2hash)(const void *index, unsigned char *hash);
|
||||||
uint32_t * ihashtable;
|
uint32_t * ihashtable;
|
||||||
uint8_t * hashvalues;
|
uint8_t * hashvalues;
|
||||||
|
uint8_t * hashhashvalues;
|
||||||
time_t compacted;
|
time_t compacted;
|
||||||
|
uint32_t ihashhashempty;
|
||||||
uint32_t ihashempty;
|
uint32_t ihashempty;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user