/*#io
docCopyright("Steve Dekorte", 2004)
docLicense("BSD revised")
docObject("SkipDB")
docDescription("A sorted key/value pair database implemented with skip lists on top of UDB.")
*/
#ifndef SkipDB_DEFINED
#define SkipDB_DEFINED 1
#if defined(WIN32)
#if defined(BUILDING_SKIPDB_DLL) || defined(BUILDING_IOVMALL_DLL)
#define SKIPDB_API __declspec(dllexport)
#else
#define SKIPDB_API __declspec(dllimport)
#endif
#else
#define SKIPDB_API
#endif
#include "SkipDBRecord.h"
#include "Hash.h"
#include "RandomGen.h"
#ifdef __cplusplus
extern "C" {
#endif
// if prob. dist = 0.5, then max level 32 is enough for 2^32 records
#define SKIPDB_MAX_LEVEL 32
#define SKIPDB_PROBABILITY_DISTRIBUTION 0.5
typedef void (SkipDBObjectMarkFunc)(void *);
typedef void (SkipDBFreeObjectFunc)(void *);
typedef struct
{
int refCount;
void *dbm;
PID_TYPE headerPid;
SkipDBRecord *header;
SkipDBRecord *youngestRecord; // most recently accessed
SkipDBRecord *update[SKIPDB_MAX_LEVEL];
float p;
BStream *stream;
SkipDBObjectMarkFunc *objectMarkFunc;
SkipDBFreeObjectFunc *objectFreeFunc;
List *cursors;
List *dirtyRecords;
List *pidsToRemove;
size_t cachedRecordCount;
size_t cacheHighWaterMark;
size_t cacheLowWaterMark;
unsigned char mark; // current record mark identifier
Hash *pidToRecord;
RandomGen *randomGen;
} SkipDB;
#include "SkipDBCursor.h"
SKIPDB_API SkipDB *SkipDB_newWithDBM_(void *dbm);
SKIPDB_API SkipDB *SkipDB_newWithDBM_atPid_(void *dbm, PID_TYPE pid);
SKIPDB_API void SkipDB_sdbm_(SkipDB *self, void *dbm);
SKIPDB_API void SkipDB_retain(SkipDB *self);
SKIPDB_API void SkipDB_release(SkipDB *self);
SKIPDB_API BStream *SkipDB_tmpStream(SkipDB *self);
SKIPDB_API void SkipDB_headerPid_(SkipDB *self, PID_TYPE pid);
SKIPDB_API PID_TYPE SkipDB_headerPid(SkipDB *self);
SKIPDB_API SkipDBRecord *SkipDB_headerRecord(SkipDB *self);
SKIPDB_API UDB *SkipDB_udb(SkipDB *self);
SKIPDB_API int SkipDB_isOpen(SkipDB *self);
SKIPDB_API int SkipDB_delete(SkipDB *self);
// notifications
SKIPDB_API void SkipDB_noteNewRecord_(SkipDB *self, SkipDBRecord *r);
SKIPDB_API void SkipDB_noteAccessedRecord_(SkipDB *self, SkipDBRecord *r);
SKIPDB_API void SkipDB_noteDirtyRecord_(SkipDB *self, SkipDBRecord *r);
SKIPDB_API void SkipDB_noteAssignedPidToRecord_(SkipDB *self, SkipDBRecord *r);
SKIPDB_API void SkipDB_noteWillFreeRecord_(SkipDB *self, SkipDBRecord *r);
// cache
SKIPDB_API void SkipDB_setCacheHighWaterMark_(SkipDB *self, size_t recordCount);
SKIPDB_API size_t SkipDB_cacheHighWaterMark(SkipDB *self);
SKIPDB_API void SkipDB_setCacheLowWaterMark_(SkipDB *self, size_t recordCount);
SKIPDB_API size_t SkipDB_cacheLowWaterMark(SkipDB *self);
SKIPDB_API void SkipDB_clearCache(SkipDB *self);
SKIPDB_API void SkipDB_freeAllCachedRecords(SkipDB *self);
SKIPDB_API int SkipDB_headerIsEmpty(SkipDB *self);
// transactions
SKIPDB_API void SkipDB_sync(SkipDB *self);
SKIPDB_API void SkipDB_saveDirtyRecords(SkipDB *self);
void SkipDB_deleteRecordsToRemove(SkipDB *self);
// record api
SKIPDB_API SkipDBRecord *SkipDB_recordAt_(SkipDB *self, Datum k);
SKIPDB_API SkipDBRecord *SkipDB_recordAt_put_(SkipDB *self, Datum k, Datum v);
// bdb style api
SKIPDB_API void SkipDB_at_put_(SkipDB *self, Datum k, Datum v);
SKIPDB_API Datum SkipDB_at_(SkipDB *self, Datum k);
SKIPDB_API void SkipDB_removeAt_(SkipDB *self, Datum k);
// compact
SKIPDB_API int SkipDB_compact(SkipDB *self);
// debugging
SKIPDB_API void SkipDB_showUpdate(SkipDB *self);
SKIPDB_API void SkipDB_show(SkipDB *self);
// private
SKIPDB_API void SkipDB_updateAt_put_(SkipDB *self, int level, SkipDBRecord *r);
SKIPDB_API SkipDBRecord *SkipDB_recordAtPid_(SkipDB *self, PID_TYPE pid);
// objects
SKIPDB_API void SkipDB_objectMarkFunc_(SkipDB *self, SkipDBObjectMarkFunc *func);
SKIPDB_API void SkipDB_freeObjectCallback_(SkipDB *, SkipDBFreeObjectFunc *func);
// cursor
SKIPDB_API int SkipDB_count(SkipDB *self);
SKIPDB_API SkipDBRecord *SkipDB_firstRecord(SkipDB *self);
SKIPDB_API SkipDBRecord *SkipDB_lastRecord(SkipDB *self);
SKIPDB_API SkipDBRecord *SkipDB_goto_(SkipDB *self, Datum key);
SKIPDB_API SkipDBCursor *SkipDB_createCursor(SkipDB *self);
SKIPDB_API void SkipDB_removeCursor_(SkipDB *self, SkipDBCursor *cursor);
// moving from in-memory to on-disk
SKIPDB_API void SkipDB_mergeInto_(SkipDB *self, SkipDB *other);
#ifdef __cplusplus
}
#endif
#endif
syntax highlighted by Code2HTML, v. 0.9.1