A O(1) lru implementation.
This commit is contained in:
parent
8145e8db6f
commit
17845a59ed
4 changed files with 87 additions and 17 deletions
|
@ -20,16 +20,23 @@
|
|||
|
||||
*/
|
||||
|
||||
#include <lladd/doubleLinkedList.h>
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -6,15 +6,12 @@
|
|||
#include <lladd/lhtable.h>
|
||||
#include <lladd/redblack.h>
|
||||
#include <lladd/replacementPolicy.h>
|
||||
#include <pthread.h>
|
||||
|
||||
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() {
|
||||
|
|
75
src/lladd/replacementPolicy/lruFast.c
Normal file
75
src/lladd/replacementPolicy/lruFast.c
Normal 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;
|
||||
}
|
Loading…
Reference in a new issue