mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
lruhash insert and lookup.
git-svn-id: file:///svn/unbound/trunk@176 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
8fb3bb8bef
commit
3f61aca920
3 changed files with 264 additions and 38 deletions
|
|
@ -1,3 +1,6 @@
|
||||||
|
14 March 2007: Wouter
|
||||||
|
- hash table insert (and subroutines) and lookup implemented.
|
||||||
|
|
||||||
13 March 2007: Wouter
|
13 March 2007: Wouter
|
||||||
- lock_unprotect in checklocks.
|
- lock_unprotect in checklocks.
|
||||||
- util/storage/lruhash.h for LRU hash table structure.
|
- util/storage/lruhash.h for LRU hash table structure.
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,9 @@
|
||||||
|
|
||||||
/* ------ local helper functions ------------- */
|
/* ------ local helper functions ------------- */
|
||||||
|
|
||||||
|
/** init the hash bins for the table. */
|
||||||
|
static void bin_init(struct lruhash_bin* array, size_t size);
|
||||||
|
|
||||||
/** delete the hash bin and entries inside it */
|
/** delete the hash bin and entries inside it */
|
||||||
static void bin_delete(struct lruhash* table, struct lruhash_bin* bin);
|
static void bin_delete(struct lruhash* table, struct lruhash_bin* bin);
|
||||||
|
|
||||||
|
|
@ -58,25 +61,83 @@ static void bin_delete(struct lruhash* table, struct lruhash_bin* bin);
|
||||||
static struct lruhash_entry* bin_find_entry(struct lruhash* table,
|
static struct lruhash_entry* bin_find_entry(struct lruhash* table,
|
||||||
struct lruhash_bin* bin, hashvalue_t hash, void* key);
|
struct lruhash_bin* bin, hashvalue_t hash, void* key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to make howmuch space available for a new entry into the table.
|
* Remove entry from bin overflow chain.
|
||||||
* works by deleting old entries.
|
* You must have locked the bin.
|
||||||
* Assumes that the lock on the hashtable is being held by caller.
|
* @param bin: hash bin to look into.
|
||||||
* @param table: hash table.
|
* @param entry: entry ptr that needs removal.
|
||||||
* @param howmuch: will try to make max-used at least this amount.
|
|
||||||
*/
|
*/
|
||||||
static void reclaim_space(struct lruhash* table, size_t howmuch);
|
static void bin_overflow_remove(struct lruhash_bin* bin,
|
||||||
|
struct lruhash_entry* entry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split hash bin into two new ones. Based on increased size_mask.
|
||||||
|
* Caller must hold hash table lock.
|
||||||
|
* At the end the routine acquires all hashbin locks (in the old array).
|
||||||
|
* This makes it wait for other threads to finish with the bins.
|
||||||
|
* So the bins are ready to be deleted after this function.
|
||||||
|
* @param table: hash table with function pointers.
|
||||||
|
* @param newa: new increased array.
|
||||||
|
* @param newmask: new lookup mask.
|
||||||
|
*/
|
||||||
|
static void bin_split(struct lruhash* table, struct lruhash_bin* newa,
|
||||||
|
int newmask);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to make space available by deleting old entries.
|
||||||
|
* Assumes that the lock on the hashtable is being held by caller.
|
||||||
|
* Caller must not hold bin locks.
|
||||||
|
* @param table: hash table.
|
||||||
|
* @param list: list of entries that are to be deleted later.
|
||||||
|
* Entries have been removed from the hash table and writelock is held.
|
||||||
|
*/
|
||||||
|
static void reclaim_space(struct lruhash* table, struct lruhash_entry** list);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Grow the table lookup array. Becomes twice as large.
|
* Grow the table lookup array. Becomes twice as large.
|
||||||
* Caller must hold the hash table lock.
|
* Caller must hold the hash table lock. Must not hold any bin locks.
|
||||||
|
* Tries to grow, on malloc failure, nothing happened.
|
||||||
* @param table: hash table.
|
* @param table: hash table.
|
||||||
* @return false on error (malloc).
|
|
||||||
*/
|
*/
|
||||||
static int table_grow(struct lruhash* table);
|
static void table_grow(struct lruhash* table);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Touch entry, so it becomes the most recently used in the LRU list.
|
||||||
|
* Caller must hold hash table lock. The entry must be inserted already.
|
||||||
|
* @param table: hash table.
|
||||||
|
* @param entry: entry to make first in LRU.
|
||||||
|
*/
|
||||||
|
static void lru_touch(struct lruhash* table, struct lruhash_entry* entry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put entry at front of lru. entry must be unlinked from lru.
|
||||||
|
* Caller must hold hash table lock.
|
||||||
|
* @param table: hash table with lru head and tail.
|
||||||
|
* @param entry: entry to make most recently used.
|
||||||
|
*/
|
||||||
|
static void lru_front(struct lruhash* table, struct lruhash_entry* entry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove entry from lru list.
|
||||||
|
* Caller must hold hash table lock.
|
||||||
|
* @param table: hash table with lru head and tail.
|
||||||
|
* @param entry: entry to remove from lru.
|
||||||
|
*/
|
||||||
|
static void lru_remove(struct lruhash* table, struct lruhash_entry* entry);
|
||||||
|
|
||||||
/* ------ end local helper functions --------- */
|
/* ------ end local helper functions --------- */
|
||||||
|
|
||||||
|
static void
|
||||||
|
bin_init(struct lruhash_bin* array, size_t size)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for(i=0; i<size; i++) {
|
||||||
|
lock_quick_init(&array[i].lock);
|
||||||
|
lock_protect(&array[i].lock, &array[i],
|
||||||
|
sizeof(struct lruhash_bin));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct lruhash* lruhash_create(size_t start_size, size_t maxmem,
|
struct lruhash* lruhash_create(size_t start_size, size_t maxmem,
|
||||||
lruhash_sizefunc_t sizefunc, lruhash_compfunc_t compfunc,
|
lruhash_sizefunc_t sizefunc, lruhash_compfunc_t compfunc,
|
||||||
lruhash_delkeyfunc_t delkeyfunc, lruhash_deldatafunc_t deldatafunc,
|
lruhash_delkeyfunc_t delkeyfunc, lruhash_deldatafunc_t deldatafunc,
|
||||||
|
|
@ -84,7 +145,6 @@ struct lruhash* lruhash_create(size_t start_size, size_t maxmem,
|
||||||
{
|
{
|
||||||
struct lruhash* table = (struct lruhash*)calloc(1,
|
struct lruhash* table = (struct lruhash*)calloc(1,
|
||||||
sizeof(struct lruhash));
|
sizeof(struct lruhash));
|
||||||
size_t i;
|
|
||||||
if(!table)
|
if(!table)
|
||||||
return NULL;
|
return NULL;
|
||||||
lock_quick_init(&table->lock);
|
lock_quick_init(&table->lock);
|
||||||
|
|
@ -94,7 +154,7 @@ struct lruhash* lruhash_create(size_t start_size, size_t maxmem,
|
||||||
table->deldatafunc = deldatafunc;
|
table->deldatafunc = deldatafunc;
|
||||||
table->cb_arg = arg;
|
table->cb_arg = arg;
|
||||||
table->size = start_size;
|
table->size = start_size;
|
||||||
table->size_mask = start_size-1;
|
table->size_mask = (int)(start_size-1);
|
||||||
table->lru_start = NULL;
|
table->lru_start = NULL;
|
||||||
table->lru_end = NULL;
|
table->lru_end = NULL;
|
||||||
table->num = 0;
|
table->num = 0;
|
||||||
|
|
@ -106,9 +166,7 @@ struct lruhash* lruhash_create(size_t start_size, size_t maxmem,
|
||||||
free(table);
|
free(table);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for(i=0; i<table->size; i++) {
|
bin_init(table->array, table->size);
|
||||||
lock_quick_init(&table->array[i].lock);
|
|
||||||
}
|
|
||||||
lock_protect(&table->lock, table, sizeof(*table));
|
lock_protect(&table->lock, table, sizeof(*table));
|
||||||
lock_protect(&table->lock, table->array,
|
lock_protect(&table->lock, table->array,
|
||||||
table->size*sizeof(struct lruhash_bin));
|
table->size*sizeof(struct lruhash_bin));
|
||||||
|
|
@ -131,6 +189,34 @@ static void bin_delete(struct lruhash* table, struct lruhash_bin* bin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bin_split(struct lruhash* table, struct lruhash_bin* newa,
|
||||||
|
int newmask)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
struct lruhash_entry *p, *np;
|
||||||
|
int newbin;
|
||||||
|
/* move entries to new table. Notice that since hash x is mapped to
|
||||||
|
* bin x & mask, and new mask uses one more bit, so all entries in
|
||||||
|
* one bin will go into the old bin or bin | newbit */
|
||||||
|
/* newbit = newmask - table->size_mask; */
|
||||||
|
/* so, really, this task could also be threaded, per bin. */
|
||||||
|
/* LRU list is not changed */
|
||||||
|
for(i=0; i<table->size; i++)
|
||||||
|
{
|
||||||
|
lock_quick_lock(&table->array[i].lock);
|
||||||
|
p = table->array[i].overflow_list;
|
||||||
|
while(p) {
|
||||||
|
np = p->overflow_next;
|
||||||
|
/* link into correct new bin */
|
||||||
|
newbin = p->hash & newmask;
|
||||||
|
p->overflow_next = newa[newbin].overflow_list;
|
||||||
|
newa[newbin].overflow_list = p;
|
||||||
|
p=np;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void lruhash_delete(struct lruhash* table)
|
void lruhash_delete(struct lruhash* table)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
@ -145,35 +231,146 @@ void lruhash_delete(struct lruhash* table)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reclaim_space(struct lruhash* table, size_t howmuch)
|
bin_overflow_remove(struct lruhash_bin* bin, struct lruhash_entry* entry)
|
||||||
{
|
{
|
||||||
|
struct lruhash_entry* p = bin->overflow_list;
|
||||||
|
struct lruhash_entry** prevp = &bin->overflow_list;
|
||||||
|
while(p) {
|
||||||
|
if(p == entry) {
|
||||||
|
*prevp = p->overflow_next;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
prevp = &p->overflow_next;
|
||||||
|
p = p->overflow_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
reclaim_space(struct lruhash* table, struct lruhash_entry** list)
|
||||||
|
{
|
||||||
|
struct lruhash_entry* d;
|
||||||
|
struct lruhash_bin* bin;
|
||||||
|
log_assert(table);
|
||||||
|
/* does not delete MRU entry, so table will not be empty. */
|
||||||
|
while(table->num > 1 && table->space_used > table->space_max) {
|
||||||
|
/* notice that since we hold the hashtable lock, nobody
|
||||||
|
can change the lru chain. So it cannot be deleted underneath
|
||||||
|
us. We still need the hashbin and entry write lock to make
|
||||||
|
sure we flush all users away from the entry.
|
||||||
|
which is unlikely, since it is LRU, if someone got a rdlock
|
||||||
|
it would be moved to front, but to be sure. */
|
||||||
|
d = table->lru_end;
|
||||||
|
/* specialised, delete from end of double linked list,
|
||||||
|
and we know num>1, so there is a previous lru entry. */
|
||||||
|
log_assert(d && d->lru_prev);
|
||||||
|
table->lru_end = d->lru_prev;
|
||||||
|
d->lru_prev->lru_next = NULL;
|
||||||
|
/* schedule entry for deletion */
|
||||||
|
bin = &table->array[d->hash & table->size_mask];
|
||||||
|
table->num --;
|
||||||
|
lock_quick_lock(&bin->lock);
|
||||||
|
bin_overflow_remove(bin, d);
|
||||||
|
d->overflow_next = *list;
|
||||||
|
*list = d;
|
||||||
|
lock_rw_wrlock(&d->lock);
|
||||||
|
table->space_used -= table->sizefunc(d->key, d->data);
|
||||||
|
lock_quick_unlock(&bin->lock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct lruhash_entry*
|
static struct lruhash_entry*
|
||||||
bin_find_entry(struct lruhash* table,
|
bin_find_entry(struct lruhash* table,
|
||||||
struct lruhash_bin* bin, hashvalue_t hash, void* key)
|
struct lruhash_bin* bin, hashvalue_t hash, void* key)
|
||||||
{
|
{
|
||||||
|
struct lruhash_entry* p = bin->overflow_list;
|
||||||
|
while(p) {
|
||||||
|
if(p->hash == hash && table->compfunc(p->key, key) == 0)
|
||||||
|
return p;
|
||||||
|
p = p->overflow_next;
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int table_grow(struct lruhash* table)
|
static void
|
||||||
|
table_grow(struct lruhash* table)
|
||||||
{
|
{
|
||||||
return 0;
|
struct lruhash_bin* newa;
|
||||||
|
int newmask;
|
||||||
|
size_t i;
|
||||||
|
if(table->size_mask == (int)(((size_t)-1)>>1)) {
|
||||||
|
log_err("hash array malloc: size_t too small");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* try to allocate new array, if not fail */
|
||||||
|
newa = calloc(table->size*2, sizeof(struct lruhash_bin));
|
||||||
|
if(!newa) {
|
||||||
|
log_err("hash grow: malloc failed");
|
||||||
|
/* continue with smaller array. Though its slower. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bin_init(newa, table->size*2);
|
||||||
|
newmask = (table->size_mask << 1) | 1;
|
||||||
|
bin_split(table, newa, newmask);
|
||||||
|
/* delete the old bins */
|
||||||
|
lock_unprotect(&table->lock, table->array);
|
||||||
|
for(i=0; i<table->size; i++) {
|
||||||
|
lock_quick_unlock(&table->array[i].lock);
|
||||||
|
lock_quick_destroy(&table->array[i].lock);
|
||||||
|
}
|
||||||
|
free(table->array);
|
||||||
|
|
||||||
|
table->size *= 2;
|
||||||
|
table->size_mask = newmask;
|
||||||
|
table->array = newa;
|
||||||
|
lock_protect(&table->lock, table->array,
|
||||||
|
table->size*sizeof(struct lruhash_bin));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
lru_front(struct lruhash* table, struct lruhash_entry* entry)
|
||||||
|
{
|
||||||
|
entry->lru_prev = NULL;
|
||||||
|
entry->lru_next = table->lru_start;
|
||||||
|
if(!table->lru_start)
|
||||||
|
table->lru_end = entry;
|
||||||
|
else table->lru_start->lru_prev = entry;
|
||||||
|
table->lru_start = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
lru_remove(struct lruhash* table, struct lruhash_entry* entry)
|
||||||
|
{
|
||||||
|
if(entry->lru_prev)
|
||||||
|
entry->lru_prev->lru_next = entry->lru_next;
|
||||||
|
else table->lru_start = entry->lru_next;
|
||||||
|
if(entry->lru_next)
|
||||||
|
entry->lru_next->lru_prev = entry->lru_prev;
|
||||||
|
else table->lru_end = entry->lru_prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
lru_touch(struct lruhash* table, struct lruhash_entry* entry)
|
||||||
|
{
|
||||||
|
log_assert(table && entry);
|
||||||
|
if(entry == table->lru_start)
|
||||||
|
return; /* nothing to do */
|
||||||
|
/* remove from current lru position */
|
||||||
|
lru_remove(table, entry);
|
||||||
|
/* add at front */
|
||||||
|
lru_front(table, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lruhash_insert(struct lruhash* table, hashvalue_t hash,
|
void lruhash_insert(struct lruhash* table, hashvalue_t hash,
|
||||||
struct lruhash_entry* entry, void* data)
|
struct lruhash_entry* entry, void* data)
|
||||||
{
|
{
|
||||||
struct lruhash_bin* bin;
|
struct lruhash_bin* bin;
|
||||||
struct lruhash_entry* found;
|
struct lruhash_entry* found, *reclaimlist=NULL;
|
||||||
size_t need_size;
|
size_t need_size;
|
||||||
lock_quick_lock(&table->lock);
|
|
||||||
/* see if table memory exceeded and needs clipping. */
|
|
||||||
need_size = table->sizefunc(entry->key, data);
|
need_size = table->sizefunc(entry->key, data);
|
||||||
if(table->space_used + need_size > table->space_max)
|
|
||||||
reclaim_space(table, need_size);
|
|
||||||
|
|
||||||
/* find bin */
|
/* find bin */
|
||||||
|
lock_quick_lock(&table->lock);
|
||||||
bin = &table->array[hash & table->size_mask];
|
bin = &table->array[hash & table->size_mask];
|
||||||
lock_quick_lock(&bin->lock);
|
lock_quick_lock(&bin->lock);
|
||||||
|
|
||||||
|
|
@ -182,31 +379,55 @@ void lruhash_insert(struct lruhash* table, hashvalue_t hash,
|
||||||
/* if not: add to bin */
|
/* if not: add to bin */
|
||||||
entry->overflow_next = bin->overflow_list;
|
entry->overflow_next = bin->overflow_list;
|
||||||
bin->overflow_list = entry;
|
bin->overflow_list = entry;
|
||||||
|
lru_front(table, entry);
|
||||||
table->num++;
|
table->num++;
|
||||||
table->space_used += need_size;
|
table->space_used += need_size;
|
||||||
} else {
|
} else {
|
||||||
/* if so: update data */
|
/* if so: update data */
|
||||||
table->space_used += need_size -
|
table->space_used += need_size -
|
||||||
(*table->sizefunc)(found->key, found->data);
|
(*table->sizefunc)(found->key, found->data);
|
||||||
entry->data = NULL;
|
|
||||||
(*table->delkeyfunc)(entry->key, table->cb_arg);
|
(*table->delkeyfunc)(entry->key, table->cb_arg);
|
||||||
(*table->deldatafunc)(found->data, table->cb_arg);
|
(*table->deldatafunc)(found->data, table->cb_arg);
|
||||||
found->data = data;
|
found->data = data;
|
||||||
|
lru_touch(table, found);
|
||||||
}
|
}
|
||||||
lock_quick_unlock(&bin->lock);
|
lock_quick_unlock(&bin->lock);
|
||||||
|
if(table->space_used > table->space_max)
|
||||||
/* see if table lookup must be grown up */
|
reclaim_space(table, &reclaimlist);
|
||||||
if(table->num == table->size) {
|
if(table->num >= table->size)
|
||||||
if(!table_grow(table))
|
table_grow(table);
|
||||||
log_err("hash grow: malloc failed");
|
|
||||||
/* continue with smaller array. Slower. */
|
|
||||||
}
|
|
||||||
lock_quick_unlock(&table->lock);
|
lock_quick_unlock(&table->lock);
|
||||||
|
|
||||||
|
/* finish reclaim if any (outside of critical region) */
|
||||||
|
while(reclaimlist) {
|
||||||
|
struct lruhash_entry* n = reclaimlist->overflow_next;
|
||||||
|
lock_rw_unlock(&reclaimlist->lock);
|
||||||
|
(*table->delkeyfunc)(reclaimlist->key, table->cb_arg);
|
||||||
|
(*table->deldatafunc)(reclaimlist->data, table->cb_arg);
|
||||||
|
reclaimlist = n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct lruhash_entry* lruhash_lookup(struct lruhash* table, void* key, int wr)
|
struct lruhash_entry* lruhash_lookup(struct lruhash* table, hashvalue_t hash,
|
||||||
|
void* key, int wr)
|
||||||
{
|
{
|
||||||
return NULL;
|
struct lruhash_entry* entry = NULL;
|
||||||
|
struct lruhash_bin* bin;
|
||||||
|
|
||||||
|
lock_quick_lock(&table->lock);
|
||||||
|
bin = &table->array[hash & table->size_mask];
|
||||||
|
lock_quick_lock(&bin->lock);
|
||||||
|
if((entry=bin_find_entry(table, bin, hash, key)))
|
||||||
|
lru_touch(table, entry);
|
||||||
|
lock_quick_unlock(&table->lock);
|
||||||
|
|
||||||
|
if(entry) {
|
||||||
|
if(wr)
|
||||||
|
lock_rw_wrlock(&entry->lock);
|
||||||
|
else lock_rw_rdlock(&entry->lock);
|
||||||
|
}
|
||||||
|
lock_quick_unlock(&bin->lock);
|
||||||
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lruhash_remove(struct lruhash* table, void* key)
|
void lruhash_remove(struct lruhash* table, void* key)
|
||||||
|
|
|
||||||
|
|
@ -194,13 +194,13 @@ struct lruhash_entry {
|
||||||
* You need to delete it to change hash or key.
|
* You need to delete it to change hash or key.
|
||||||
*/
|
*/
|
||||||
lock_rw_t lock;
|
lock_rw_t lock;
|
||||||
/** next entry in overflow chain */
|
/** next entry in overflow chain. Covered by hashlock and binlock. */
|
||||||
struct lruhash_entry* overflow_next;
|
struct lruhash_entry* overflow_next;
|
||||||
/** next entry in lru chain */
|
/** next entry in lru chain. covered by hashlock. */
|
||||||
struct lruhash_entry* lru_next;
|
struct lruhash_entry* lru_next;
|
||||||
/** prev entry in lru chain */
|
/** prev entry in lru chain. covered by hashlock. */
|
||||||
struct lruhash_entry* lru_prev;
|
struct lruhash_entry* lru_prev;
|
||||||
/** hash value of the key */
|
/** hash value of the key. It may not change, until entry deleted. */
|
||||||
hashvalue_t hash;
|
hashvalue_t hash;
|
||||||
/** key */
|
/** key */
|
||||||
void* key;
|
void* key;
|
||||||
|
|
@ -255,6 +255,7 @@ void lruhash_insert(struct lruhash* table, hashvalue_t hash,
|
||||||
* At the end of the function you hold a (read/write)lock on the entry.
|
* At the end of the function you hold a (read/write)lock on the entry.
|
||||||
* The LRU is updated for the entry (if found).
|
* The LRU is updated for the entry (if found).
|
||||||
* @param table: hash table.
|
* @param table: hash table.
|
||||||
|
* @param hash: hash of key.
|
||||||
* @param key: what to look for, compared against entries in overflow chain.
|
* @param key: what to look for, compared against entries in overflow chain.
|
||||||
* the hash value must be set, and must work with compare function.
|
* the hash value must be set, and must work with compare function.
|
||||||
* @param wr: set to true if you desire a writelock on the entry.
|
* @param wr: set to true if you desire a writelock on the entry.
|
||||||
|
|
@ -262,7 +263,8 @@ void lruhash_insert(struct lruhash* table, hashvalue_t hash,
|
||||||
* @return: pointer to the entry or NULL. The entry is locked.
|
* @return: pointer to the entry or NULL. The entry is locked.
|
||||||
* The user must unlock the entry when done.
|
* The user must unlock the entry when done.
|
||||||
*/
|
*/
|
||||||
struct lruhash_entry* lruhash_lookup(struct lruhash* table, void* key, int wr);
|
struct lruhash_entry* lruhash_lookup(struct lruhash* table, hashvalue_t hash,
|
||||||
|
void* key, int wr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove entry from hashtable. Does nothing if not found in hashtable.
|
* Remove entry from hashtable. Does nothing if not found in hashtable.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue