cache.c
/* Search the cache for a matching entry and return it when found. If
this fails search the negative cache and return (void *) -1 if this
search was successful. Otherwise return NULL.
This function must be called with the read-lock held. */
struct datahead *
cache_search (request_type type, const void *key, size_t len,
struct database_dyn *table, uid_t owner)
{
unsigned long int hash = __nss_hash (key, len) % table->head->module;
unsigned long int nsearched = 0;
struct datahead *result = NULL;
ref_t work = table->head->array[hash];
while (work != ENDREF)
{
++nsearched;
struct hashentry *here = (struct hashentry *) (table->data + work);
if (type == here->type && len == here->len
&& memcmp (key, table->data + here->key, len) == 0
&& here->owner == owner)
{
/* We found the entry. Increment the appropriate counter. */
struct datahead *dh
= (struct datahead *) (table->data + here->packet);
/* See whether we must ignore the entry. */
if (dh->usable)
{
/* We do not synchronize the memory here. The statistics
data is not crucial, we synchronize only once in a while
in the cleanup threads. */
if (dh->notfound)
++table->head->neghit;
else
{
++table->head->poshit;
if (dh->nreloads != 0)
dh->nreloads = 0;
}
result = dh;
break;
}
}
work = here->next;
}
if (nsearched > table->head->maxnsearched)
table->head->maxnsearched = nsearched;
return result;
}