stasis-aries-wal/stasis/operations/lsmTree.h
2010-01-21 00:03:17 +00:00

156 lines
5 KiB
C

#ifndef _LSMTREE_H__
#define _LSMTREE_H__
/**
@file
A log structured merge tree implementation. This implementation
performs atomic bulk append operations to reduce logging overheads,
and does not support in place updates.
However, once written, the page format of internal nodes is similar
to that of a conventional b-tree, while leaf nodes may be provided
by any page type that allows records to be appendend to a page, and
read by slot id.
For now, LSM-trees only support fixed length keys; this restriction
will be lifted in the future.
*/
#include <stasis/common.h>
#include <stasis/iterator.h>
#include <assert.h>
typedef struct {
recordid treeRoot;
recordid pos;
} lladd_lsm_iterator;
typedef int(*lsm_comparator_t)(const void* a, const void* b);
typedef void*(*lsm_page_initializer_t)(Page *, void *);
typedef pageid_t(*lsm_page_allocator_t)(int, void *);
typedef void(*lsm_page_deallocator_t)(int, void *);
typedef void(*lsm_page_forcer_t)(int, void *);
void lsmTreeRegisterComparator(int id, lsm_comparator_t i);
void lsmTreeRegisterPageInitializer(int id, lsm_page_initializer_t i);
pageid_t TlsmRegionAlloc(int xid, void *conf);
pageid_t TlsmRegionAllocRid(int xid, void *conf);
void TlsmRegionForceRid(int xid, void *conf);
typedef struct {
recordid regionList;
pageid_t regionCount;
pageid_t nextPage;
pageid_t endOfRegion;
pageid_t regionSize;
} TlsmRegionAllocConf_t;
void TlsmRegionDeallocRid(int xid, void *conf);
extern TlsmRegionAllocConf_t LSM_REGION_ALLOC_STATIC_INITIALIZER;
/**
Initialize a new LSM tree.
@param xid The tranasction that is creating the tree.
@param comparator The id of the comparator this tree should use.
(It must have been registered with lsmTreeRegisterComparator
before TlsmCreate() is called.
@param allocator A callback that will return an allocated page when called.
This is used as the tree is extended.
@param allocator_state A pointer that will be paseed into allocator
when it is called.
@param keySize
*/
recordid TlsmCreate(int xid, int comparator,
lsm_page_allocator_t allocator, void *allocator_state,
int keySize);
/**
Free the space associated with an LSM tree.
*/
recordid TlsmDealloc(int xid,
lsm_page_allocator_t allocator, void *allocator_state,
recordid tree);
/**
Append a new leaf page to an LSM tree. Leaves must be appended in
ascending order; LSM trees do not support update in place.
*/
recordid TlsmAppendPage(int xid, recordid tree,
const byte *key,
lsm_page_allocator_t allocator, void *allocator_state,
long pageid);
void TlsmForce(int xid, recordid tree, lsm_page_forcer_t force,
void *allocator_state);
void TlsmFree(int xid, recordid tree, lsm_page_deallocator_t dealloc,
void *allocator_state);
/**
Lookup a leaf page.
@param xid The transaction that is looking up this page
@param tree The tree to be queried.
@param key The value you're looking for. The first page that may
contain this value will be returned. (lsmTree supports
duplicate keys...) LSM trees currently store fixed
length keys, so there is no keySize parameter.
*/
pageid_t TlsmFindPage(int xid, recordid tree,
const byte *key);
/**
@todo TlsmFirstPage for symmetry?
*/
pageid_t TlsmLastPage(int xid, recordid tree);
/// --------------- Iterator implementation
typedef struct lsmTreeNodeRecord {
pageid_t ptr;
} lsmTreeNodeRecord;
typedef struct lsmIteratorImpl {
Page * p;
recordid current;
lsmTreeNodeRecord *t;
int justOnePage;
} lsmIteratorImpl;
/**
Return a forward iterator over the tree's leaf pages (*not* their
contents). The iterator starts before the first leaf page.
@see iterator.h for documentation of lsmTree's iterator interface.
*/
lladdIterator_t* lsmTreeIterator_open(int xid, recordid tree);
/**
Return a forward iterator over the tree's leaf pages, starting
on the given page.
*/
lladdIterator_t* lsmTreeIterator_openAt(int xid, recordid tree, const byte* key);
/*
These are the functions that implement lsmTree's iterator.
They're public so that performance critical code can call them
without paying for a virtual method invocation.
*/
void lsmTreeIterator_close(int xid, lladdIterator_t * it);
int lsmTreeIterator_next (int xid, lladdIterator_t * it);
lladdIterator_t *lsmTreeIterator_copy(int xid, lladdIterator_t* i);
static inline int lsmTreeIterator_key (int xid, lladdIterator_t *it,
byte **key) {
lsmIteratorImpl * impl = (lsmIteratorImpl*)it->impl;
*key = (byte*)(impl->t+1);
return impl->current.size;
}
static inline int lsmTreeIterator_value(int xid, lladdIterator_t *it,
byte **value) {
lsmIteratorImpl * impl = (lsmIteratorImpl*)it->impl;
*value = (byte*)&(impl->t->ptr);
return sizeof(impl->t->ptr);
}
static inline void lsmTreeIterator_tupleDone(int xid, void *it) { }
static inline void lsmTreeIterator_releaseLock(int xid, void *it) { }
#endif // _LSMTREE_H__