A O(1) lru implementation.

This commit is contained in:
Sears Russell 2007-03-11 07:45:17 +00:00
parent 8145e8db6f
commit 17845a59ed
4 changed files with 87 additions and 17 deletions

View file

@ -20,16 +20,23 @@
*/ */
#include <lladd/doubleLinkedList.h>
typedef struct replacementPolicy { typedef struct replacementPolicy {
struct replacementPolicy* (*init)(); struct replacementPolicy* (*init)();
void (*deinit) (struct replacementPolicy* impl); 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*(*getStale)(struct replacementPolicy* impl);
void*(*remove) (struct replacementPolicy* impl, int id); void*(*remove) (struct replacementPolicy* impl, void * page);
void (*insert) (struct replacementPolicy* impl, int id, void * page); void (*insert) (struct replacementPolicy* impl, void * page);
void * impl; void * impl;
} replacementPolicy; } replacementPolicy;
replacementPolicy * lruInit(); 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);

View file

@ -3,7 +3,7 @@
lib_LIBRARIES=liblladd.a lib_LIBRARIES=liblladd.a
#liblladd_a_LIBADD=logger/liblogger.a operations/liboperations.a #liblladd_a_LIBADD=logger/liblogger.a operations/liboperations.a
# removed: recovery.c transactional.c logger.c logger/logparser.c logger/logstreamer.c # 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 \ pageFile.c pageCache.c page.c bufferPool.c blobManager.c recovery2.c truncation.c \
transactional2.c allocationPolicy.c \ transactional2.c allocationPolicy.c \
lockManager.c iterator.c consumer.c arrayCollection.c ringbuffer.c fifo.c multiplexer.c graph.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 \ operations/regions.c \
io/rangeTracker.c io/memory.c io/file.c io/non_blocking.c io/debug.c \ io/rangeTracker.c io/memory.c io/file.c io/non_blocking.c io/debug.c \
bufferManager/pageArray.c bufferManager/bufferHash.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 # page/header.c logger/logMemory.c \ ringbuffer.c \ asdfas
#operations/lladdhash.c #operations/lladdhash.c
#AM_CFLAGS= -g -Wall -pedantic -std=gnu99 #AM_CFLAGS= -g -Wall -pedantic -std=gnu99

View file

@ -6,15 +6,12 @@
#include <lladd/lhtable.h> #include <lladd/lhtable.h>
#include <lladd/redblack.h> #include <lladd/redblack.h>
#include <lladd/replacementPolicy.h> #include <lladd/replacementPolicy.h>
#include <pthread.h>
typedef struct entry { typedef struct entry {
void * value; void * value;
uint64_t clock; uint64_t clock;
} entry; } entry;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
typedef struct lru { typedef struct lru {
uint64_t now; uint64_t now;
struct LH_ENTRY(table) * hash; struct LH_ENTRY(table) * hash;
@ -43,7 +40,6 @@ static void lruDeinit(replacementPolicy* r) {
/** @todo handle clock wraps properly! */ /** @todo handle clock wraps properly! */
static void lruHit(replacementPolicy* r, int id) { static void lruHit(replacementPolicy* r, int id) {
pthread_mutex_lock(&mut);
lru * l = r->impl; lru * l = r->impl;
entry * e = LH_ENTRY(find)(l->hash, &id, sizeof(int)); entry * e = LH_ENTRY(find)(l->hash, &id, sizeof(int));
assert(e); assert(e);
@ -53,17 +49,13 @@ static void lruHit(replacementPolicy* r, int id) {
l->now++; l->now++;
old = (entry *)RB_ENTRY(search)(e, l->lru); old = (entry *)RB_ENTRY(search)(e, l->lru);
assert(e == old); assert(e == old);
pthread_mutex_unlock(&mut);
} }
static void * lruGetStale(replacementPolicy* r) { static void * lruGetStale(replacementPolicy* r) {
pthread_mutex_lock(&mut);
lru * l = r->impl; lru * l = r->impl;
entry * e = (entry * ) RB_ENTRY(min)(l->lru); entry * e = (entry * ) RB_ENTRY(min)(l->lru);
pthread_mutex_unlock(&mut);
return e ? e->value : 0; return e ? e->value : 0;
} }
static void* lruRemove(replacementPolicy* r, int id) { static void* lruRemove(replacementPolicy* r, int id) {
pthread_mutex_lock(&mut);
lru * l = r->impl; lru * l = r->impl;
entry * e = LH_ENTRY(remove)(l->hash, &id, sizeof(int)); entry * e = LH_ENTRY(remove)(l->hash, &id, sizeof(int));
assert(e); assert(e);
@ -71,11 +63,9 @@ static void* lruRemove(replacementPolicy* r, int id) {
assert(old == e); assert(old == e);
void * ret = e->value; void * ret = e->value;
free(e); free(e);
pthread_mutex_unlock(&mut);
return ret; return ret;
} }
static void lruInsert(replacementPolicy* r, int id, void * p) { static void lruInsert(replacementPolicy* r, int id, void * p) {
pthread_mutex_lock(&mut);
lru * l = r->impl; lru * l = r->impl;
entry * e = LH_ENTRY(find)(l->hash, &id, sizeof(int)); entry * e = LH_ENTRY(find)(l->hash, &id, sizeof(int));
assert(!e); assert(!e);
@ -86,8 +76,6 @@ static void lruInsert(replacementPolicy* r, int id, void * p) {
LH_ENTRY(insert)(l->hash, &id, sizeof(int), e); LH_ENTRY(insert)(l->hash, &id, sizeof(int), e);
entry * old = (entry *) RB_ENTRY(search)(e, l->lru); entry * old = (entry *) RB_ENTRY(search)(e, l->lru);
assert(e == old); assert(e == old);
pthread_mutex_unlock(&mut);
} }
replacementPolicy * lruInit() { replacementPolicy * lruInit() {

View file

@ -0,0 +1,75 @@
#include <config.h>
#include <stdlib.h>
#include <lladd/replacementPolicy.h>
//#include <lladd/lhtable.h>
#include <lladd/doubleLinkedList.h>
#include <assert.h>
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;
}