From 92939d20facb6fef1da94bcb21f043f1d5e09eca Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Thu, 11 Jun 2015 13:33:13 +0200 Subject: [PATCH] MINOR: lru: Add lru64_lookup function It lookup a key in a LRU cache for use with specified domain and revision. It differs from lru64_get as it does not create missing keys. The function returns NULL if an error or a cache miss occurs. --- include/import/lru.h | 2 ++ src/lru.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/include/import/lru.h b/include/import/lru.h index f922449b2..220cb17f6 100644 --- a/include/import/lru.h +++ b/include/import/lru.h @@ -66,6 +66,8 @@ struct lru64 { void (*free)(void *data); /* function to release data, if needed */ }; + +struct lru64 *lru64_lookup(unsigned long long key, struct lru64_head *lru, void *domain, unsigned long long revision); struct lru64 *lru64_get(unsigned long long key, struct lru64_head *lru, void *domain, unsigned long long revision); void lru64_commit(struct lru64 *elem, void *data, void *domain, unsigned long long revision, void (*free)(void *)); struct lru64_head *lru64_new(int size); diff --git a/src/lru.c b/src/lru.c index 1b997d8b8..273f3a886 100644 --- a/src/lru.c +++ b/src/lru.c @@ -28,6 +28,41 @@ #define LIST_ADD(lh, el) ({ (el)->n = (lh)->n; (el)->n->p = (lh)->n = (el); (el)->p = (lh); }) #define LIST_DEL(el) ({ (el)->n->p = (el)->p; (el)->p->n = (el)->n; }) + +/* Lookup key in LRU cache for use with domain whose data's + * current version is . It differs from lru64_get as it does not + * create missing keys. The function returns NULL if an error or a cache miss + * occurs. */ +struct lru64 *lru64_lookup(unsigned long long key, struct lru64_head *lru, + void *domain, unsigned long long revision) +{ + struct eb64_node *node; + struct lru64 *elem; + + if (!lru->spare) { + if (!lru->cache_size) + return NULL; + lru->spare = malloc(sizeof(*lru->spare)); + if (!lru->spare) + return NULL; + lru->spare->domain = NULL; + } + + node = __eb64_lookup(&lru->keys, key); + elem = container_of(node, typeof(*elem), node); + if (elem) { + /* Existing entry found, check validity then move it at the + * head of the LRU list. + */ + if (elem->domain == domain && elem->revision == revision) { + LIST_DEL(&elem->lru); + LIST_ADD(&lru->list, &elem->lru); + return elem; + } + } + return NULL; +} + /* Get key from LRU cache for use with domain whose data's * current revision is . If the key doesn't exist it's first created * with ->domain = NULL. The caller detects this situation by checking ->domain