Fixes a number of memory leaks; adds pageCleanup() callback, and allows callers to use custom allocators with LSM trees
This commit is contained in:
parent
9c1c284406
commit
5bd2138a8b
19 changed files with 78 additions and 17 deletions
|
@ -4,7 +4,7 @@ LDADD=$(top_builddir)/src/stasis/libstasis.la \
|
||||||
if BUILD_BENCHMARKS
|
if BUILD_BENCHMARKS
|
||||||
noinst_PROGRAMS=lhtableThreaded naiveHash logicalHash readLogicalHash naiveMultiThreaded logicalMultThreaded rawSet \
|
noinst_PROGRAMS=lhtableThreaded naiveHash logicalHash readLogicalHash naiveMultiThreaded logicalMultThreaded rawSet \
|
||||||
arrayListSet logicalMultiReaders linearHashNTA linkedListNTA pageOrientedListNTA \
|
arrayListSet logicalMultiReaders linearHashNTA linkedListNTA pageOrientedListNTA \
|
||||||
linearHashNTAThreaded linearHashNTAMultiReader linearHashNTAWriteRequests transitiveClosure zeroCopy
|
linearHashNTAThreaded linearHashNTAMultiReader linearHashNTAWriteRequests transitiveClosure zeroCopy sequentialThroughput
|
||||||
endif
|
endif
|
||||||
AM_CFLAGS=${GLOBAL_CFLAGS}
|
AM_CFLAGS=${GLOBAL_CFLAGS}
|
||||||
|
|
||||||
|
|
3
clean.sh
3
clean.sh
|
@ -5,6 +5,9 @@ find . | grep \~$ | xargs rm -f
|
||||||
find . -name '*.bb' | xargs rm -f
|
find . -name '*.bb' | xargs rm -f
|
||||||
find . -name '*.bbg' | xargs rm -f
|
find . -name '*.bbg' | xargs rm -f
|
||||||
find . -name '*.da' | xargs rm -f
|
find . -name '*.da' | xargs rm -f
|
||||||
|
find . -name '*.o' | xargs rm -f
|
||||||
|
find . -name '*.lo' | xargs rm -f
|
||||||
|
find . -name '*.Plo' | xargs rm -f
|
||||||
find . | perl -ne 'print if (/\/core(\.\d+)?$/)' | xargs rm -f
|
find . | perl -ne 'print if (/\/core(\.\d+)?$/)' | xargs rm -f
|
||||||
find . | perl -ne 'print if (/\/Makefile.in$/)' | xargs rm -f
|
find . | perl -ne 'print if (/\/Makefile.in$/)' | xargs rm -f
|
||||||
find . | perl -ne 'print if (/\/storefile.txt$/)' | xargs rm -f
|
find . | perl -ne 'print if (/\/storefile.txt$/)' | xargs rm -f
|
||||||
|
|
|
@ -15,7 +15,8 @@ libstasis_la_SOURCES=crc32.c redblack.c lhtable.c doubleLinkedList.c common.c fl
|
||||||
operations/linearHashNTA.c operations/linkedListNTA.c \
|
operations/linearHashNTA.c operations/linkedListNTA.c \
|
||||||
operations/pageOrientedListNTA.c operations/bTree.c \
|
operations/pageOrientedListNTA.c operations/bTree.c \
|
||||||
operations/regions.c operations/lsmTree.c \
|
operations/regions.c operations/lsmTree.c \
|
||||||
io/rangeTracker.c io/memory.c io/file.c io/pfile.c io/non_blocking.c io/debug.c \
|
io/rangeTracker.c io/memory.c io/file.c io/pfile.c io/non_blocking.c \
|
||||||
|
io/debug.c \
|
||||||
bufferManager/pageArray.c bufferManager/bufferHash.c \
|
bufferManager/pageArray.c bufferManager/bufferHash.c \
|
||||||
replacementPolicy/lru.c replacementPolicy/lruFast.c
|
replacementPolicy/lru.c replacementPolicy/lruFast.c
|
||||||
AM_CFLAGS=${GLOBAL_CFLAGS}
|
AM_CFLAGS=${GLOBAL_CFLAGS}
|
||||||
|
|
|
@ -231,10 +231,12 @@ void allocationPolicyDeinit(allocationPolicy * ap) {
|
||||||
RB_ENTRY(delete)(next, ap->availablePages);
|
RB_ENTRY(delete)(next, ap->availablePages);
|
||||||
free((void*)next);
|
free((void*)next);
|
||||||
}
|
}
|
||||||
|
|
||||||
LH_ENTRY(destroy)(ap->xidAlloced);
|
LH_ENTRY(destroy)(ap->xidAlloced);
|
||||||
|
LH_ENTRY(destroy)(ap->xidDealloced);
|
||||||
RB_ENTRY(destroy)(ap->availablePages);
|
RB_ENTRY(destroy)(ap->availablePages);
|
||||||
LH_ENTRY(destroy)(ap->pageOwners);
|
LH_ENTRY(destroy)(ap->pageOwners);
|
||||||
|
LH_ENTRY(destroy)(ap->allPages);
|
||||||
|
|
||||||
free(ap);
|
free(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,12 +63,13 @@ void writeBlob(int xid, Page * p2, lsn_t lsn, recordid rid, const byte * buf) {
|
||||||
|
|
||||||
static int notSupported(int xid, Page * p) { return 0; }
|
static int notSupported(int xid, Page * p) { return 0; }
|
||||||
|
|
||||||
void blobLoaded(Page *p) {
|
static void blobLoaded(Page *p) {
|
||||||
p->LSN = *lsn_ptr(p);
|
p->LSN = *lsn_ptr(p);
|
||||||
}
|
}
|
||||||
void blobFlushed(Page *p) {
|
static void blobFlushed(Page *p) {
|
||||||
*lsn_ptr(p) = p->LSN;
|
*lsn_ptr(p) = p->LSN;
|
||||||
}
|
}
|
||||||
|
static void blobCleanup(Page *p) { }
|
||||||
|
|
||||||
static page_impl pi = {
|
static page_impl pi = {
|
||||||
BLOB_PAGE,
|
BLOB_PAGE,
|
||||||
|
@ -93,6 +94,7 @@ static page_impl pi = {
|
||||||
0, //XXX page_impl_dereference_identity,
|
0, //XXX page_impl_dereference_identity,
|
||||||
blobLoaded,
|
blobLoaded,
|
||||||
blobFlushed,
|
blobFlushed,
|
||||||
|
blobCleanup
|
||||||
};
|
};
|
||||||
page_impl blobImpl() {
|
page_impl blobImpl() {
|
||||||
return pi;
|
return pi;
|
||||||
|
|
|
@ -109,6 +109,7 @@ inline static Page * writeBackOnePage() {
|
||||||
|
|
||||||
// printf("Write(%ld)\n", (long)victim->id);
|
// printf("Write(%ld)\n", (long)victim->id);
|
||||||
pageWrite(victim);
|
pageWrite(victim);
|
||||||
|
pageCleanup(victim);
|
||||||
// Make sure that no one mistakenly thinks this is still a live copy.
|
// Make sure that no one mistakenly thinks this is still a live copy.
|
||||||
victim->id = -1;
|
victim->id = -1;
|
||||||
|
|
||||||
|
@ -277,6 +278,7 @@ static void bhBufDeinit() {
|
||||||
LH_ENTRY(openlist)(cachedPages, &iter);
|
LH_ENTRY(openlist)(cachedPages, &iter);
|
||||||
while((next = LH_ENTRY(readlist)(&iter))) {
|
while((next = LH_ENTRY(readlist)(&iter))) {
|
||||||
pageWrite((next->value));
|
pageWrite((next->value));
|
||||||
|
pageCleanup((next->value)); // normally called by writeBackOnePage()
|
||||||
}
|
}
|
||||||
LH_ENTRY(closelist)(&iter);
|
LH_ENTRY(closelist)(&iter);
|
||||||
LH_ENTRY(destroy)(cachedPages);
|
LH_ENTRY(destroy)(cachedPages);
|
||||||
|
@ -299,6 +301,7 @@ static void bhSimulateBufferManagerCrash() {
|
||||||
Page * p = next->value;
|
Page * p = next->value;
|
||||||
writelock(p->rwlatch,0);
|
writelock(p->rwlatch,0);
|
||||||
pageFlushed(p); // normally, pageWrite() would call this...
|
pageFlushed(p); // normally, pageWrite() would call this...
|
||||||
|
pageCleanup(p); // normally called by writeBackOnePage()
|
||||||
unlock(p->rwlatch);
|
unlock(p->rwlatch);
|
||||||
}
|
}
|
||||||
LH_ENTRY(closelist)(&iter);
|
LH_ENTRY(closelist)(&iter);
|
||||||
|
@ -331,7 +334,7 @@ void bhBufInit() {
|
||||||
|
|
||||||
cachedPages = LH_ENTRY(create)(MAX_BUFFER_SIZE);
|
cachedPages = LH_ENTRY(create)(MAX_BUFFER_SIZE);
|
||||||
|
|
||||||
freeListLength = MAX_BUFFER_SIZE / 10;
|
freeListLength = 9 * MAX_BUFFER_SIZE / 10;
|
||||||
freeLowWater = freeListLength - 5;
|
freeLowWater = freeListLength - 5;
|
||||||
freeCount = 0;
|
freeCount = 0;
|
||||||
pageCount = 0;
|
pageCount = 0;
|
||||||
|
|
|
@ -160,6 +160,9 @@ void TallocInit() {
|
||||||
allocPolicy = allocationPolicyInit();
|
allocPolicy = allocationPolicyInit();
|
||||||
// pthread_mutex_init(&talloc_mutex, NULL);
|
// pthread_mutex_init(&talloc_mutex, NULL);
|
||||||
}
|
}
|
||||||
|
void TallocDeinit() {
|
||||||
|
allocationPolicyDeinit(allocPolicy);
|
||||||
|
}
|
||||||
|
|
||||||
static void reserveNewRegion(int xid) {
|
static void reserveNewRegion(int xid) {
|
||||||
int firstPage = TregionAlloc(xid, TALLOC_REGION_SIZE, STORAGE_MANAGER_TALLOC);
|
int firstPage = TregionAlloc(xid, TALLOC_REGION_SIZE, STORAGE_MANAGER_TALLOC);
|
||||||
|
|
|
@ -76,6 +76,19 @@ void lsmTreeRegisterComparator(int id, lsm_comparator_t i) {
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static pageid_t defaultAllocator(int xid, void *ignored) {
|
||||||
|
return TpageAlloc(xid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static pageid_t (*pageAllocator)(int xid, void *ignored) = defaultAllocator;
|
||||||
|
static void *pageAllocatorConfig;
|
||||||
|
void TlsmSetPageAllocator(pageid_t (*allocer)(int xid, void * ignored),
|
||||||
|
void * config) {
|
||||||
|
pageAllocator = allocer;
|
||||||
|
pageAllocatorConfig = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct lsmTreeState {
|
typedef struct lsmTreeState {
|
||||||
pageid_t lastLeaf;
|
pageid_t lastLeaf;
|
||||||
|
@ -119,7 +132,7 @@ static void initializeNodePage(int xid, Page *p, size_t keylen) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline size_t getKeySizeFixed(int xid, Page const *p) {
|
static inline size_t getKeySizeFixed(int xid, Page const *p) {
|
||||||
return *recordsize_ptr(p) - sizeof(lsmTreeNodeRecord);
|
return (*recordsize_ptr(p)) - sizeof(lsmTreeNodeRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t getKeySizeVirtualMethods(int xid, Page *p) {
|
static inline size_t getKeySizeVirtualMethods(int xid, Page *p) {
|
||||||
|
@ -190,7 +203,7 @@ recordid TlsmCreate(int xid, int comparator, int keySize) {
|
||||||
assert(HEADER_SIZE + 2 * (sizeof(lsmTreeNodeRecord) +keySize) <
|
assert(HEADER_SIZE + 2 * (sizeof(lsmTreeNodeRecord) +keySize) <
|
||||||
USABLE_SIZE_OF_PAGE - 2 * sizeof(short));
|
USABLE_SIZE_OF_PAGE - 2 * sizeof(short));
|
||||||
|
|
||||||
pageid_t root = TpageAlloc(xid);
|
pageid_t root = pageAllocator(xid, pageAllocatorConfig);
|
||||||
DEBUG("Root = %lld\n", root);
|
DEBUG("Root = %lld\n", root);
|
||||||
recordid ret = { root, 0, 0 };
|
recordid ret = { root, 0, 0 };
|
||||||
|
|
||||||
|
@ -237,7 +250,7 @@ static recordid buildPathToLeaf(int xid, recordid root, Page *root_p,
|
||||||
assert(depth);
|
assert(depth);
|
||||||
DEBUG("buildPathToLeaf(depth=%d) (lastleaf=%lld) called\n",depth, lastLeaf);
|
DEBUG("buildPathToLeaf(depth=%d) (lastleaf=%lld) called\n",depth, lastLeaf);
|
||||||
|
|
||||||
pageid_t child = TpageAlloc(xid); // XXX Use some other function...
|
pageid_t child = pageAllocator(xid, pageAllocatorConfig); // XXX Use some other function...
|
||||||
DEBUG("new child = %lld internal? %d\n", child, depth-1);
|
DEBUG("new child = %lld internal? %d\n", child, depth-1);
|
||||||
|
|
||||||
Page *child_p = loadPage(xid, child);
|
Page *child_p = loadPage(xid, child);
|
||||||
|
@ -316,6 +329,8 @@ static recordid appendInternalNode(int xid, Page *p,
|
||||||
int depth,
|
int depth,
|
||||||
const byte *key, size_t key_len,
|
const byte *key, size_t key_len,
|
||||||
pageid_t val_page, pageid_t lastLeaf) {
|
pageid_t val_page, pageid_t lastLeaf) {
|
||||||
|
assert(*page_type_ptr(p) == LSM_ROOT_PAGE ||
|
||||||
|
*page_type_ptr(p) == FIXED_PAGE);
|
||||||
if(!depth) {
|
if(!depth) {
|
||||||
// leaf node.
|
// leaf node.
|
||||||
recordid ret = recordPreAlloc(xid, p, sizeof(lsmTreeNodeRecord)+key_len);
|
recordid ret = recordPreAlloc(xid, p, sizeof(lsmTreeNodeRecord)+key_len);
|
||||||
|
@ -449,7 +464,7 @@ recordid TlsmAppendPage(int xid, recordid tree,
|
||||||
if(ret.size == INVALID_SLOT) {
|
if(ret.size == INVALID_SLOT) {
|
||||||
DEBUG("Need to split root; depth = %d\n", depth);
|
DEBUG("Need to split root; depth = %d\n", depth);
|
||||||
|
|
||||||
pageid_t child = TpageAlloc(xid);
|
pageid_t child = pageAllocator(xid, pageAllocatorConfig);
|
||||||
Page *lc = loadPage(xid, child);
|
Page *lc = loadPage(xid, child);
|
||||||
writelock(lc->rwlatch,0);
|
writelock(lc->rwlatch,0);
|
||||||
|
|
||||||
|
@ -629,15 +644,17 @@ pageid_t TlsmFindPage(int xid, recordid tree, const byte *key) {
|
||||||
associated with the tree.
|
associated with the tree.
|
||||||
*/
|
*/
|
||||||
static void lsmPageLoaded(Page *p) {
|
static void lsmPageLoaded(Page *p) {
|
||||||
|
/// XXX should call fixedLoaded, or something...
|
||||||
lsmTreeState *state = malloc(sizeof(lsmTreeState));
|
lsmTreeState *state = malloc(sizeof(lsmTreeState));
|
||||||
state->lastLeaf = -1;
|
state->lastLeaf = -1;
|
||||||
p->impl = state;
|
p->impl = state;
|
||||||
}
|
}
|
||||||
|
static void lsmPageFlushed(Page *p) { }
|
||||||
/**
|
/**
|
||||||
Free any soft state associated with the tree rooted at page p.
|
Free any soft state associated with the tree rooted at page p.
|
||||||
This is called by the buffer manager.
|
This is called by the buffer manager.
|
||||||
*/
|
*/
|
||||||
static void lsmPageFlushed(Page *p) {
|
static void lsmPageCleanup(Page *p) {
|
||||||
lsmTreeState *state = p->impl;
|
lsmTreeState *state = p->impl;
|
||||||
free(state);
|
free(state);
|
||||||
}
|
}
|
||||||
|
@ -648,6 +665,7 @@ page_impl lsmRootImpl() {
|
||||||
page_impl pi = fixedImpl();
|
page_impl pi = fixedImpl();
|
||||||
pi.pageLoaded = lsmPageLoaded;
|
pi.pageLoaded = lsmPageLoaded;
|
||||||
pi.pageFlushed = lsmPageFlushed;
|
pi.pageFlushed = lsmPageFlushed;
|
||||||
|
pi.pageCleanup = lsmPageCleanup;
|
||||||
pi.page_type = LSM_ROOT_PAGE;
|
pi.page_type = LSM_ROOT_PAGE;
|
||||||
return pi;
|
return pi;
|
||||||
}
|
}
|
||||||
|
@ -706,7 +724,7 @@ int lsmTreeIterator_next(int xid, lladdIterator_t *it) {
|
||||||
impl->current = fixedNext(xid, impl->p, impl->current);
|
impl->current = fixedNext(xid, impl->p, impl->current);
|
||||||
if(impl->current.size == INVALID_SLOT) {
|
if(impl->current.size == INVALID_SLOT) {
|
||||||
const lsmTreeNodeRecord *next_rec = readNodeRecord(xid,impl->p,NEXT_LEAF,
|
const lsmTreeNodeRecord *next_rec = readNodeRecord(xid,impl->p,NEXT_LEAF,
|
||||||
impl->current.size);
|
keySize);
|
||||||
unlock(impl->p->rwlatch);
|
unlock(impl->p->rwlatch);
|
||||||
releasePage(impl->p);
|
releasePage(impl->p);
|
||||||
|
|
||||||
|
@ -722,6 +740,9 @@ int lsmTreeIterator_next(int xid, lladdIterator_t *it) {
|
||||||
impl->p = 0;
|
impl->p = 0;
|
||||||
impl->current.size = -1;
|
impl->current.size = -1;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
assert(impl->current.size == keySize + sizeof(lsmTreeNodeRecord));
|
||||||
|
impl->current.size = keySize;
|
||||||
}
|
}
|
||||||
if(impl->current.size != INVALID_SLOT) {
|
if(impl->current.size != INVALID_SLOT) {
|
||||||
impl->t = readNodeRecord(xid,impl->p,impl->current.slot,impl->current.size);
|
impl->t = readNodeRecord(xid,impl->p,impl->current.slot,impl->current.size);
|
||||||
|
|
|
@ -63,6 +63,9 @@ pblHashTable_t * nestedTopActions = NULL;
|
||||||
void initNestedTopActions() {
|
void initNestedTopActions() {
|
||||||
nestedTopActions = pblHtCreate();
|
nestedTopActions = pblHtCreate();
|
||||||
}
|
}
|
||||||
|
void deinitNestedTopActions() {
|
||||||
|
pblHtDelete(nestedTopActions);
|
||||||
|
}
|
||||||
/** @todo TbeginNestedTopAction's API might not be quite right.
|
/** @todo TbeginNestedTopAction's API might not be quite right.
|
||||||
Are there cases where we need to pass a recordid in?
|
Are there cases where we need to pass a recordid in?
|
||||||
|
|
||||||
|
|
|
@ -322,6 +322,13 @@ void pageFlushed(Page * p){
|
||||||
*lsn_ptr(p) = p->LSN;
|
*lsn_ptr(p) = p->LSN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void pageCleanup(Page * p) {
|
||||||
|
short type = *page_type_ptr(p);
|
||||||
|
if(type) {
|
||||||
|
assert(page_impls[type].page_type == type);
|
||||||
|
page_impls[type].pageCleanup(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Generic block implementations
|
/// Generic block implementations
|
||||||
|
|
||||||
|
|
|
@ -272,7 +272,7 @@ int pageFreespace(int xid, Page * p);
|
||||||
void pageCompact(Page * p);
|
void pageCompact(Page * p);
|
||||||
void pageLoaded(Page * p);
|
void pageLoaded(Page * p);
|
||||||
void pageFlushed(Page * p);
|
void pageFlushed(Page * p);
|
||||||
|
void pageCleanup(Page * p);
|
||||||
/**
|
/**
|
||||||
@return -1 if the field does not exist, the size of the field otherwise (the rid parameter's size field will be ignored).
|
@return -1 if the field does not exist, the size of the field otherwise (the rid parameter's size field will be ignored).
|
||||||
*/
|
*/
|
||||||
|
@ -581,6 +581,7 @@ typedef struct page_impl {
|
||||||
This function should record p->LSN somewhere appropriate
|
This function should record p->LSN somewhere appropriate
|
||||||
*/
|
*/
|
||||||
void (*pageFlushed)(Page * p);
|
void (*pageFlushed)(Page * p);
|
||||||
|
void (*pageCleanup)(Page * p);
|
||||||
} page_impl;
|
} page_impl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -79,6 +79,7 @@ static int fixedGetLength(int xid, Page *p, recordid rid) {
|
||||||
return rid.slot > *recordcount_ptr(p) ?
|
return rid.slot > *recordcount_ptr(p) ?
|
||||||
INVALID_SLOT : physical_slot_length(*recordsize_ptr(p));
|
INVALID_SLOT : physical_slot_length(*recordsize_ptr(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int notSupported(int xid, Page * p) { return 0; }
|
static int notSupported(int xid, Page * p) { return 0; }
|
||||||
|
|
||||||
static int fixedFreespace(int xid, Page * p) {
|
static int fixedFreespace(int xid, Page * p) {
|
||||||
|
@ -129,6 +130,7 @@ void fixedLoaded(Page *p) {
|
||||||
void fixedFlushed(Page *p) {
|
void fixedFlushed(Page *p) {
|
||||||
*lsn_ptr(p) = p->LSN;
|
*lsn_ptr(p) = p->LSN;
|
||||||
}
|
}
|
||||||
|
void fixedCleanup(Page *p) { }
|
||||||
page_impl fixedImpl() {
|
page_impl fixedImpl() {
|
||||||
static page_impl pi = {
|
static page_impl pi = {
|
||||||
FIXED_PAGE,
|
FIXED_PAGE,
|
||||||
|
@ -153,6 +155,7 @@ page_impl fixedImpl() {
|
||||||
0, // XXX dereference
|
0, // XXX dereference
|
||||||
fixedLoaded, // loaded
|
fixedLoaded, // loaded
|
||||||
fixedFlushed, // flushed
|
fixedFlushed, // flushed
|
||||||
|
fixedCleanup
|
||||||
};
|
};
|
||||||
return pi;
|
return pi;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#ifndef __FIXED_H
|
#ifndef __FIXED_H
|
||||||
#define __FIXED_H
|
#define __FIXED_H
|
||||||
|
// @todo rename fixed.h macros to something more specific
|
||||||
#define recordsize_ptr(page) shorts_from_end((page), 1)
|
#define recordsize_ptr(page) shorts_from_end((page), 1)
|
||||||
#define recordcount_ptr(page) shorts_from_end((page), 2)
|
#define recordcount_ptr(page) shorts_from_end((page), 2)
|
||||||
#define fixed_record_ptr(page, n) bytes_from_start((page), *recordsize_ptr((page)) * (n))
|
#define fixed_record_ptr(page, n) bytes_from_start((page), *recordsize_ptr((page)) * (n))
|
||||||
|
|
|
@ -242,7 +242,7 @@ void indirectLoaded(Page *p) {
|
||||||
void indirectFlushed(Page *p) {
|
void indirectFlushed(Page *p) {
|
||||||
*lsn_ptr(p) = p->LSN;
|
*lsn_ptr(p) = p->LSN;
|
||||||
}
|
}
|
||||||
|
void indirectCleanup(Page *p) { }
|
||||||
static page_impl pi = {
|
static page_impl pi = {
|
||||||
INDIRECT_PAGE,
|
INDIRECT_PAGE,
|
||||||
0, //read,
|
0, //read,
|
||||||
|
@ -266,6 +266,7 @@ static page_impl pi = {
|
||||||
0, //XXX page_impl_dereference_identity,
|
0, //XXX page_impl_dereference_identity,
|
||||||
indirectLoaded,
|
indirectLoaded,
|
||||||
indirectFlushed,
|
indirectFlushed,
|
||||||
|
indirectCleanup
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -507,6 +507,7 @@ void slottedFlushed(Page *p) {
|
||||||
*lsn_ptr(p) = p->LSN;
|
*lsn_ptr(p) = p->LSN;
|
||||||
slottedFsck(p);
|
slottedFsck(p);
|
||||||
}
|
}
|
||||||
|
void slottedCleanup(Page *p) { }
|
||||||
|
|
||||||
page_impl slottedImpl() {
|
page_impl slottedImpl() {
|
||||||
static page_impl pi = {
|
static page_impl pi = {
|
||||||
|
@ -532,6 +533,7 @@ static page_impl pi = {
|
||||||
0, //XXX page_impl_dereference_identity,
|
0, //XXX page_impl_dereference_identity,
|
||||||
slottedLoaded,
|
slottedLoaded,
|
||||||
slottedFlushed,
|
slottedFlushed,
|
||||||
|
slottedCleanup
|
||||||
};
|
};
|
||||||
return pi;
|
return pi;
|
||||||
}
|
}
|
||||||
|
|
|
@ -408,6 +408,8 @@ int Tdeinit() {
|
||||||
assert( numActiveXactions == 0 );
|
assert( numActiveXactions == 0 );
|
||||||
truncationDeinit();
|
truncationDeinit();
|
||||||
ThashDeinit();
|
ThashDeinit();
|
||||||
|
TallocDeinit();
|
||||||
|
deinitNestedTopActions();
|
||||||
bufDeinit();
|
bufDeinit();
|
||||||
DEBUG("Closing page file tdeinit\n");
|
DEBUG("Closing page file tdeinit\n");
|
||||||
closePageFile();
|
closePageFile();
|
||||||
|
|
|
@ -21,7 +21,7 @@ void allocTransactionAbort(int xid);
|
||||||
void allocTransactionCommit(int xid);
|
void allocTransactionCommit(int xid);
|
||||||
|
|
||||||
void TallocInit();
|
void TallocInit();
|
||||||
|
void TallocDeinit();
|
||||||
/**
|
/**
|
||||||
Allocate a record.
|
Allocate a record.
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,12 @@ recordid TlsmDealloc(int xid, recordid tree);
|
||||||
recordid TlsmAppendPage(int xid, recordid tree,
|
recordid TlsmAppendPage(int xid, recordid tree,
|
||||||
const byte *key,
|
const byte *key,
|
||||||
long pageid);
|
long pageid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Override the page allocation algorithm that LSM tree uses by default
|
||||||
|
*/
|
||||||
|
void TlsmSetPageAllocator(pageid_t (*allocer)(int xid, void * ignored),
|
||||||
|
void * config);
|
||||||
/**
|
/**
|
||||||
Lookup a leaf page.
|
Lookup a leaf page.
|
||||||
|
|
||||||
|
@ -92,7 +98,7 @@ static inline int lsmTreeIterator_key (int xid, lladdIterator_t *it,
|
||||||
byte **key) {
|
byte **key) {
|
||||||
lsmIteratorImpl * impl = (lsmIteratorImpl*)it->impl;
|
lsmIteratorImpl * impl = (lsmIteratorImpl*)it->impl;
|
||||||
*key = (byte*)(impl->t+1);
|
*key = (byte*)(impl->t+1);
|
||||||
return sizeof(impl->current.size);
|
return impl->current.size;
|
||||||
|
|
||||||
}
|
}
|
||||||
static inline int lsmTreeIterator_value(int xid, lladdIterator_t *it,
|
static inline int lsmTreeIterator_value(int xid, lladdIterator_t *it,
|
||||||
|
|
|
@ -57,6 +57,7 @@ terms specified in this license.
|
||||||
#define __NESTED_TOP_ACTIONS_H__
|
#define __NESTED_TOP_ACTIONS_H__
|
||||||
|
|
||||||
void initNestedTopActions();
|
void initNestedTopActions();
|
||||||
|
void deinitNestedTopActions();
|
||||||
void * TbeginNestedTopAction(int xid, int op, const byte* log_arguments, int log_arguments_length);
|
void * TbeginNestedTopAction(int xid, int op, const byte* log_arguments, int log_arguments_length);
|
||||||
lsn_t TendNestedTopAction(int xid, void * handle);
|
lsn_t TendNestedTopAction(int xid, void * handle);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue