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 {
|
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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
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