From 17845a59edc10221e8910a8f851b1e214c176e84 Mon Sep 17 00:00:00 2001 From: Sears Russell Date: Sun, 11 Mar 2007 07:45:17 +0000 Subject: [PATCH] A O(1) lru implementation. --- lladd/replacementPolicy.h | 13 +++-- src/lladd/Makefile.am | 4 +- src/lladd/replacementPolicy/lru.c | 12 ----- src/lladd/replacementPolicy/lruFast.c | 75 +++++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 17 deletions(-) create mode 100644 src/lladd/replacementPolicy/lruFast.c diff --git a/lladd/replacementPolicy.h b/lladd/replacementPolicy.h index 6f7714a..6d28780 100644 --- a/lladd/replacementPolicy.h +++ b/lladd/replacementPolicy.h @@ -20,16 +20,23 @@ */ +#include typedef struct replacementPolicy { struct replacementPolicy* (*init)(); void (*deinit) (struct replacementPolicy* impl); - void (*hit) (struct replacementPolicy* impl, int id); + void (*hit) (struct replacementPolicy* impl, void * page); void*(*getStale)(struct replacementPolicy* impl); - void*(*remove) (struct replacementPolicy* impl, int id); - void (*insert) (struct replacementPolicy* impl, int id, void * page); + void*(*remove) (struct replacementPolicy* impl, void * page); + void (*insert) (struct replacementPolicy* impl, void * page); void * impl; } replacementPolicy; replacementPolicy * lruInit(); +replacementPolicy * lruFastInit( + struct LL_ENTRY(node_t) * (*getNode)(void * page, void * conf), + void (*setNode)(void * page, + struct LL_ENTRY(node_t) * n, + void * conf), + void * conf); diff --git a/src/lladd/Makefile.am b/src/lladd/Makefile.am index ab6e363..d10ba73 100644 --- a/src/lladd/Makefile.am +++ b/src/lladd/Makefile.am @@ -3,7 +3,7 @@ lib_LIBRARIES=liblladd.a #liblladd_a_LIBADD=logger/liblogger.a operations/liboperations.a # removed: recovery.c transactional.c logger.c logger/logparser.c logger/logstreamer.c -liblladd_a_SOURCES=crc32.c redblack.c lhtable.c common.c stats.c io.c bufferManager.c linkedlist.c operations.c \ +liblladd_a_SOURCES=crc32.c redblack.c lhtable.c doubleLinkedList.c common.c stats.c io.c bufferManager.c linkedlist.c operations.c \ pageFile.c pageCache.c page.c bufferPool.c blobManager.c recovery2.c truncation.c \ transactional2.c allocationPolicy.c \ lockManager.c iterator.c consumer.c arrayCollection.c ringbuffer.c fifo.c multiplexer.c graph.c\ @@ -20,7 +20,7 @@ liblladd_a_SOURCES=crc32.c redblack.c lhtable.c common.c stats.c io.c bufferMana operations/regions.c \ io/rangeTracker.c io/memory.c io/file.c io/non_blocking.c io/debug.c \ bufferManager/pageArray.c bufferManager/bufferHash.c \ - replacementPolicy/lru.c + replacementPolicy/lru.c replacementPolicy/lruFast.c # page/header.c logger/logMemory.c \ ringbuffer.c \ asdfas #operations/lladdhash.c #AM_CFLAGS= -g -Wall -pedantic -std=gnu99 diff --git a/src/lladd/replacementPolicy/lru.c b/src/lladd/replacementPolicy/lru.c index 558f569..c9771c8 100644 --- a/src/lladd/replacementPolicy/lru.c +++ b/src/lladd/replacementPolicy/lru.c @@ -6,15 +6,12 @@ #include #include #include -#include typedef struct entry { void * value; uint64_t clock; } entry; -pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; - typedef struct lru { uint64_t now; struct LH_ENTRY(table) * hash; @@ -43,7 +40,6 @@ static void lruDeinit(replacementPolicy* r) { /** @todo handle clock wraps properly! */ static void lruHit(replacementPolicy* r, int id) { - pthread_mutex_lock(&mut); lru * l = r->impl; entry * e = LH_ENTRY(find)(l->hash, &id, sizeof(int)); assert(e); @@ -53,17 +49,13 @@ static void lruHit(replacementPolicy* r, int id) { l->now++; old = (entry *)RB_ENTRY(search)(e, l->lru); assert(e == old); - pthread_mutex_unlock(&mut); } static void * lruGetStale(replacementPolicy* r) { - pthread_mutex_lock(&mut); lru * l = r->impl; entry * e = (entry * ) RB_ENTRY(min)(l->lru); - pthread_mutex_unlock(&mut); return e ? e->value : 0; } static void* lruRemove(replacementPolicy* r, int id) { - pthread_mutex_lock(&mut); lru * l = r->impl; entry * e = LH_ENTRY(remove)(l->hash, &id, sizeof(int)); assert(e); @@ -71,11 +63,9 @@ static void* lruRemove(replacementPolicy* r, int id) { assert(old == e); void * ret = e->value; free(e); - pthread_mutex_unlock(&mut); return ret; } static void lruInsert(replacementPolicy* r, int id, void * p) { - pthread_mutex_lock(&mut); lru * l = r->impl; entry * e = LH_ENTRY(find)(l->hash, &id, sizeof(int)); assert(!e); @@ -86,8 +76,6 @@ static void lruInsert(replacementPolicy* r, int id, void * p) { LH_ENTRY(insert)(l->hash, &id, sizeof(int), e); entry * old = (entry *) RB_ENTRY(search)(e, l->lru); assert(e == old); - pthread_mutex_unlock(&mut); - } replacementPolicy * lruInit() { diff --git a/src/lladd/replacementPolicy/lruFast.c b/src/lladd/replacementPolicy/lruFast.c new file mode 100644 index 0000000..6c33118 --- /dev/null +++ b/src/lladd/replacementPolicy/lruFast.c @@ -0,0 +1,75 @@ +#include +#include +#include +//#include +#include +#include + +typedef LL_ENTRY(value_t) value_t; +typedef struct LL_ENTRY(node_t) node_t; +typedef struct LL_ENTRY(list) list; + +typedef struct lruFast { + // struct LH_ENTRY(table) * hash; + struct LL_ENTRY(list) * lru; + node_t * (*getNode)(void * page, void * conf); + void (*setNode)(void * page, node_t * n, + void * conf); + void * conf; +} lruFast; + +static void hit(struct replacementPolicy * r, void * p) { + lruFast * l = r->impl; + // node_t * n = LH_ENTRY(find)(l->hash, &id, sizeof(int)); + node_t * n = l->getNode(p, l->conf); + assert(n); + LL_ENTRY(removeNoFree)(l->lru, n); + LL_ENTRY(pushNode)(l->lru, n); +} +static void* getStale(struct replacementPolicy * r) { + lruFast * l = r->impl; + return LL_ENTRY(head)(l->lru); +} +static void* remove(struct replacementPolicy* r, void * p) { + lruFast * l = r->impl; + node_t * n = l->getNode(p, l->conf); //LH_ENTRY(remove)(l->hash, &id, sizeof(int)); + assert(n); + value_t * v = n->v; + LL_ENTRY(remove)(l->lru, n); + return v; +} +static void insert(struct replacementPolicy* r, + void * p) { + lruFast * l = r->impl; + node_t * n = LL_ENTRY(push)(l->lru, p); + // LH_ENTRY(insert)(l->hash, &id, sizeof(int), n); + l->setNode(p, n, l->conf); +} +static void deinit(struct replacementPolicy * r) { + lruFast * l = r->impl; + // the node_t's get freed by LL_ENTRY. It's the caller's + // responsibility to free the void *'s passed into us. + //LH_ENTRY(destroy)(l->hash); + LL_ENTRY(destroy)(l->lru); + free(r); +} +replacementPolicy * lruFastInit( + struct LL_ENTRY(node_t) * (*getNode)(void * page, void * conf), + void (*setNode)(void * page, + struct LL_ENTRY(node_t) * n, + void * conf), + void * conf) { + struct replacementPolicy * ret = malloc(sizeof(struct replacementPolicy)); + ret->deinit = deinit; + ret->hit = hit; + ret->getStale = getStale; + ret->remove = remove; + ret->insert = insert; + lruFast * l = malloc(sizeof(lruFast)); + // l->hash = LH_ENTRY(create)(256); + l->lru = LL_ENTRY(create)(); + l->getNode = getNode; + l->setNode = setNode; + ret->impl = l; + return ret; +}