#ifndef _LSM_INT_H
#define _LSM_INT_H
#include "lsm.h"
#include <assert.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#ifdef _WIN32
# ifdef _MSC_VER
# define snprintf _snprintf
# endif
#else
# include <unistd.h>
#endif
#ifdef NDEBUG
# ifdef LSM_DEBUG_EXPENSIVE
# undef LSM_DEBUG_EXPENSIVE
# endif
# ifdef LSM_DEBUG
# undef LSM_DEBUG
# endif
#else
# ifndef LSM_DEBUG
# define LSM_DEBUG
# endif
#endif
#define LSM_DFLT_PAGE_SIZE (4 * 1024)
#define LSM_DFLT_BLOCK_SIZE (1 * 1024 * 1024)
#define LSM_DFLT_AUTOFLUSH (1 * 1024 * 1024)
#define LSM_DFLT_AUTOCHECKPOINT (i64)(2 * 1024 * 1024)
#define LSM_DFLT_AUTOWORK 1
#define LSM_DFLT_LOG_SIZE (128*1024)
#define LSM_DFLT_AUTOMERGE 4
#define LSM_DFLT_SAFETY LSM_SAFETY_NORMAL
#define LSM_DFLT_MMAP (LSM_IS_64_BIT ? 1 : 32768)
#define LSM_DFLT_MULTIPLE_PROCESSES 1
#define LSM_DFLT_USE_LOG 1
#define LSM_CKSUM0_INIT 42
#define LSM_CKSUM1_INIT 42
#define LSM_IS_64_BIT (sizeof(void*)==8)
#define LSM_AUTOWORK_QUANT 32
typedef struct Database Database;
typedef struct DbLog DbLog;
typedef struct FileSystem FileSystem;
typedef struct Freelist Freelist;
typedef struct FreelistEntry FreelistEntry;
typedef struct Level Level;
typedef struct LogMark LogMark;
typedef struct LogRegion LogRegion;
typedef struct LogWriter LogWriter;
typedef struct LsmString LsmString;
typedef struct Mempool Mempool;
typedef struct Merge Merge;
typedef struct MergeInput MergeInput;
typedef struct MetaPage MetaPage;
typedef struct MultiCursor MultiCursor;
typedef struct Page Page;
typedef struct Redirect Redirect;
typedef struct Segment Segment;
typedef struct SegmentMerger SegmentMerger;
typedef struct ShmChunk ShmChunk;
typedef struct ShmHeader ShmHeader;
typedef struct ShmReader ShmReader;
typedef struct Snapshot Snapshot;
typedef struct TransMark TransMark;
typedef struct Tree Tree;
typedef struct TreeCursor TreeCursor;
typedef struct TreeHeader TreeHeader;
typedef struct TreeMark TreeMark;
typedef struct TreeRoot TreeRoot;
#ifndef _SQLITEINT_H_
typedef unsigned char u8;
typedef unsigned short int u16;
typedef unsigned int u32;
typedef lsm_i64 i64;
typedef unsigned long long int u64;
#endif
typedef i64 LsmPgno;
#ifdef LSM_DEBUG
int lsmErrorBkpt(int);
#else
# define lsmErrorBkpt(x) (x)
#endif
#define LSM_PROTOCOL_BKPT lsmErrorBkpt(LSM_PROTOCOL)
#define LSM_IOERR_BKPT lsmErrorBkpt(LSM_IOERR)
#define LSM_NOMEM_BKPT lsmErrorBkpt(LSM_NOMEM)
#define LSM_CORRUPT_BKPT lsmErrorBkpt(LSM_CORRUPT)
#define LSM_MISUSE_BKPT lsmErrorBkpt(LSM_MISUSE)
#define unused_parameter(x) (void)(x)
#define array_size(x) (sizeof(x)/sizeof(x[0]))
#define LSM_SHM_CHUNK_SIZE (32*1024)
#define LSM_SHM_CHUNK_HDR (sizeof(ShmChunk))
#define LSM_LOCK_NREADER 6
#define LSM_LOCK_NRWCLIENT 16
#define LSM_LOCK_DMS1 1
#define LSM_LOCK_DMS2 2
#define LSM_LOCK_DMS3 3
#define LSM_LOCK_WRITER 4
#define LSM_LOCK_WORKER 5
#define LSM_LOCK_CHECKPOINTER 6
#define LSM_LOCK_ROTRANS 7
#define LSM_LOCK_READER(i) ((i) + LSM_LOCK_ROTRANS + 1)
#define LSM_LOCK_RWCLIENT(i) ((i) + LSM_LOCK_READER(LSM_LOCK_NREADER))
#define LSM_N_LOCK LSM_LOCK_RWCLIENT(LSM_LOCK_NRWCLIENT)
#define LSM_META_PAGE_SIZE 4096
#define LSM_META_RW_PAGE_SIZE (LSM_META_PAGE_SIZE - LSM_N_LOCK)
#define LSM_MAX_FREELIST_ENTRIES 24
#define LSM_MAX_BLOCK_REDIRECTS 16
#define LSM_ATTEMPTS_BEFORE_PROTOCOL 10000
#define LSM_START_DELETE 0x01
#define LSM_END_DELETE 0x02
#define LSM_POINT_DELETE 0x04
#define LSM_INSERT 0x08
#define LSM_SEPARATOR 0x10
#define LSM_SYSTEMKEY 0x20
#define LSM_CONTIGUOUS 0x40
struct LsmString {
lsm_env *pEnv;
int n;
int nAlloc;
char *z;
};
typedef struct LsmFile LsmFile;
struct LsmFile {
lsm_file *pFile;
LsmFile *pNext;
};
typedef struct IntArray IntArray;
struct IntArray {
int nAlloc;
int nArray;
u32 *aArray;
};
struct Redirect {
int n;
struct RedirectEntry {
int iFrom;
int iTo;
} *a;
};
struct TreeMark {
u32 iRoot;
u32 nHeight;
u32 iWrite;
u32 nChunk;
u32 iFirst;
u32 iNextShmid;
int iRollback;
};
struct LogMark {
i64 iOff;
int nBuf;
u8 aBuf[8];
u32 cksum0;
u32 cksum1;
};
struct TransMark {
TreeMark tree;
LogMark log;
};
struct LogRegion {
i64 iStart;
i64 iEnd;
};
struct DbLog {
u32 cksum0;
u32 cksum1;
i64 iSnapshotId;
LogRegion aRegion[3];
};
struct TreeRoot {
u32 iRoot;
u32 nHeight;
u32 nByte;
u32 iTransId;
};
struct TreeHeader {
u32 iUsedShmid;
u32 iNextShmid;
u32 iFirst;
u32 nChunk;
TreeRoot root;
u32 iWrite;
TreeRoot oldroot;
u32 iOldShmid;
u32 iUsrVersion;
i64 iOldLog;
u32 oldcksum0;
u32 oldcksum1;
DbLog log;
u32 aCksum[2];
};
struct lsm_db {
lsm_env *pEnv;
int (*xCmp)(void *, int, void *, int);
int eSafety;
int bAutowork;
int nTreeLimit;
int nMerge;
int bUseLog;
int nDfltPgsz;
int nDfltBlksz;
int nMaxFreelist;
int iMmap;
i64 nAutockpt;
int bMultiProc;
int bReadonly;
lsm_compress compress;
lsm_compress_factory factory;
FileSystem *pFS;
Database *pDatabase;
int iRwclient;
Snapshot *pClient;
int iReader;
int bRoTrans;
MultiCursor *pCsr;
LogWriter *pLogWriter;
int nTransOpen;
int nTransAlloc;
TransMark *aTrans;
IntArray rollback;
int bDiscardOld;
MultiCursor *pCsrCache;
Snapshot *pWorker;
Freelist *pFreelist;
int bUseFreelist;
int bIncrMerge;
int bInFactory;
void (*xLog)(void *, int, const char *);
void *pLogCtx;
void (*xWork)(lsm_db *, void *);
void *pWorkCtx;
u64 mLock;
lsm_db *pNext;
int nShm;
void **apShm;
ShmHeader *pShmhdr;
TreeHeader treehdr;
u32 aSnapshot[LSM_META_PAGE_SIZE / sizeof(u32)];
};
struct Segment {
LsmPgno iFirst;
LsmPgno iLastPg;
LsmPgno iRoot;
LsmPgno nSize;
Redirect *pRedirect;
};
struct Level {
Segment lhs;
int nRight;
Segment *aRhs;
int iSplitTopic;
void *pSplitKey;
int nSplitKey;
u16 iAge;
u16 flags;
Merge *pMerge;
Level *pNext;
};
#define LEVEL_FREELIST_ONLY 0x0001
#define LEVEL_INCOMPLETE 0x0002
struct MergeInput {
LsmPgno iPg;
int iCell;
};
struct Merge {
int nInput;
MergeInput *aInput;
MergeInput splitkey;
int nSkip;
int iOutputOff;
LsmPgno iCurrentPtr;
};
#define segmentHasSeparators(pSegment) ((pSegment)->sep.iFirst>0)
struct ShmReader {
u32 iTreeId;
i64 iLsmId;
};
struct ShmHeader {
u32 aSnap1[LSM_META_PAGE_SIZE / 4];
u32 aSnap2[LSM_META_PAGE_SIZE / 4];
u32 bWriter;
u32 iMetaPage;
TreeHeader hdr1;
TreeHeader hdr2;
ShmReader aReader[LSM_LOCK_NREADER];
};
struct ShmChunk {
u32 iShmid;
u32 iNext;
};
#define LSM_MAX_SHMCHUNKS (1<<30)
#define shm_sequence_ge(a, b) (((u32)a-(u32)b) < LSM_MAX_SHMCHUNKS)
#define LSM_APPLIST_SZ 4
struct Freelist {
FreelistEntry *aEntry;
int nEntry;
int nAlloc;
};
struct FreelistEntry {
u32 iBlk;
i64 iId;
};
struct Snapshot {
Database *pDatabase;
u32 iCmpId;
Level *pLevel;
i64 iId;
i64 iLogOff;
Redirect redirect;
int nBlock;
LsmPgno aiAppend[LSM_APPLIST_SZ];
Freelist freelist;
u32 nWrite;
};
#define LSM_INITIAL_SNAPSHOT_ID 11
int lsmCheckpointWrite(lsm_db *, u32 *);
int lsmCheckpointLevels(lsm_db *, int, void **, int *);
int lsmCheckpointLoadLevels(lsm_db *pDb, void *pVal, int nVal);
int lsmCheckpointRecover(lsm_db *);
int lsmCheckpointDeserialize(lsm_db *, int, u32 *, Snapshot **);
int lsmCheckpointLoadWorker(lsm_db *pDb);
int lsmCheckpointStore(lsm_db *pDb, int);
int lsmCheckpointLoad(lsm_db *pDb, int *);
int lsmCheckpointLoadOk(lsm_db *pDb, int);
int lsmCheckpointClientCacheOk(lsm_db *);
u32 lsmCheckpointNBlock(u32 *);
i64 lsmCheckpointId(u32 *, int);
u32 lsmCheckpointNWrite(u32 *, int);
i64 lsmCheckpointLogOffset(u32 *);
int lsmCheckpointPgsz(u32 *);
int lsmCheckpointBlksz(u32 *);
void lsmCheckpointLogoffset(u32 *aCkpt, DbLog *pLog);
void lsmCheckpointZeroLogoffset(lsm_db *);
int lsmCheckpointSaveWorker(lsm_db *pDb, int);
int lsmDatabaseFull(lsm_db *pDb);
int lsmCheckpointSynced(lsm_db *pDb, i64 *piId, i64 *piLog, u32 *pnWrite);
int lsmCheckpointSize(lsm_db *db, int *pnByte);
int lsmInfoCompressionId(lsm_db *db, u32 *piCmpId);
int lsmTreeNew(lsm_env *, int (*)(void *, int, void *, int), Tree **ppTree);
void lsmTreeRelease(lsm_env *, Tree *);
int lsmTreeInit(lsm_db *);
int lsmTreeRepair(lsm_db *);
void lsmTreeMakeOld(lsm_db *pDb);
void lsmTreeDiscardOld(lsm_db *pDb);
int lsmTreeHasOld(lsm_db *pDb);
int lsmTreeSize(lsm_db *);
int lsmTreeEndTransaction(lsm_db *pDb, int bCommit);
int lsmTreeLoadHeader(lsm_db *pDb, int *);
int lsmTreeLoadHeaderOk(lsm_db *, int);
int lsmTreeInsert(lsm_db *pDb, void *pKey, int nKey, void *pVal, int nVal);
int lsmTreeDelete(lsm_db *db, void *pKey1, int nKey1, void *pKey2, int nKey2);
void lsmTreeRollback(lsm_db *pDb, TreeMark *pMark);
void lsmTreeMark(lsm_db *pDb, TreeMark *pMark);
int lsmTreeCursorNew(lsm_db *pDb, int, TreeCursor **);
void lsmTreeCursorDestroy(TreeCursor *);
int lsmTreeCursorSeek(TreeCursor *pCsr, void *pKey, int nKey, int *pRes);
int lsmTreeCursorNext(TreeCursor *pCsr);
int lsmTreeCursorPrev(TreeCursor *pCsr);
int lsmTreeCursorEnd(TreeCursor *pCsr, int bLast);
void lsmTreeCursorReset(TreeCursor *pCsr);
int lsmTreeCursorKey(TreeCursor *pCsr, int *pFlags, void **ppKey, int *pnKey);
int lsmTreeCursorFlags(TreeCursor *pCsr);
int lsmTreeCursorValue(TreeCursor *pCsr, void **ppVal, int *pnVal);
int lsmTreeCursorValid(TreeCursor *pCsr);
int lsmTreeCursorSave(TreeCursor *pCsr);
void lsmFlagsToString(int flags, char *zFlags);
void *lsmMalloc(lsm_env*, size_t);
void lsmFree(lsm_env*, void *);
void *lsmRealloc(lsm_env*, void *, size_t);
void *lsmReallocOrFree(lsm_env*, void *, size_t);
void *lsmReallocOrFreeRc(lsm_env *, void *, size_t, int *);
void *lsmMallocZeroRc(lsm_env*, size_t, int *);
void *lsmMallocRc(lsm_env*, size_t, int *);
void *lsmMallocZero(lsm_env *pEnv, size_t);
char *lsmMallocStrdup(lsm_env *pEnv, const char *);
int lsmMutexStatic(lsm_env*, int, lsm_mutex **);
int lsmMutexNew(lsm_env*, lsm_mutex **);
void lsmMutexDel(lsm_env*, lsm_mutex *);
void lsmMutexEnter(lsm_env*, lsm_mutex *);
int lsmMutexTry(lsm_env*, lsm_mutex *);
void lsmMutexLeave(lsm_env*, lsm_mutex *);
#ifndef NDEBUG
int lsmMutexHeld(lsm_env *, lsm_mutex *);
int lsmMutexNotHeld(lsm_env *, lsm_mutex *);
#endif
int lsmFsOpen(lsm_db *, const char *, int);
int lsmFsOpenLog(lsm_db *, int *);
void lsmFsCloseLog(lsm_db *);
void lsmFsClose(FileSystem *);
int lsmFsUnmap(FileSystem *);
int lsmFsConfigure(lsm_db *db);
int lsmFsBlockSize(FileSystem *);
void lsmFsSetBlockSize(FileSystem *, int);
int lsmFsMoveBlock(FileSystem *pFS, Segment *pSeg, int iTo, int iFrom);
int lsmFsPageSize(FileSystem *);
void lsmFsSetPageSize(FileSystem *, int);
int lsmFsFileid(lsm_db *pDb, void **ppId, int *pnId);
void lsmFsGobble(lsm_db *, Segment *, LsmPgno *, int);
int lsmFsSortedDelete(FileSystem *, Snapshot *, int, Segment *);
int lsmFsSortedFinish(FileSystem *, Segment *);
int lsmFsSortedAppend(FileSystem *, Snapshot *, Level *, int, Page **);
int lsmFsSortedPadding(FileSystem *, Snapshot *, Segment *);
lsm_env *lsmFsEnv(FileSystem *);
lsm_env *lsmPageEnv(Page *);
FileSystem *lsmPageFS(Page *);
int lsmFsSectorSize(FileSystem *);
void lsmSortedSplitkey(lsm_db *, Level *, int *);
int lsmFsDbPageLast(FileSystem *pFS, Segment *pSeg, Page **ppPg);
int lsmFsDbPageGet(FileSystem *, Segment *, LsmPgno, Page **);
int lsmFsDbPageNext(Segment *, Page *, int eDir, Page **);
u8 *lsmFsPageData(Page *, int *);
int lsmFsPageRelease(Page *);
int lsmFsPagePersist(Page *);
void lsmFsPageRef(Page *);
LsmPgno lsmFsPageNumber(Page *);
int lsmFsNRead(FileSystem *);
int lsmFsNWrite(FileSystem *);
int lsmFsMetaPageGet(FileSystem *, int, int, MetaPage **);
int lsmFsMetaPageRelease(MetaPage *);
u8 *lsmFsMetaPageData(MetaPage *, int *);
#ifdef LSM_DEBUG
int lsmFsDbPageIsLast(Segment *pSeg, Page *pPg);
int lsmFsIntegrityCheck(lsm_db *);
#endif
LsmPgno lsmFsRedirectPage(FileSystem *, Redirect *, LsmPgno);
int lsmFsPageWritable(Page *);
int lsmFsWriteLog(FileSystem *pFS, i64 iOff, LsmString *pStr);
int lsmFsSyncLog(FileSystem *pFS);
int lsmFsReadLog(FileSystem *pFS, i64 iOff, int nRead, LsmString *pStr);
int lsmFsTruncateLog(FileSystem *pFS, i64 nByte);
int lsmFsTruncateDb(FileSystem *pFS, i64 nByte);
int lsmFsCloseAndDeleteLog(FileSystem *pFS);
LsmFile *lsmFsDeferClose(FileSystem *pFS);
int lsmFsSyncDb(FileSystem *, int);
void lsmFsFlushWaiting(FileSystem *, int *);
int lsmInfoArrayStructure(lsm_db *pDb, int bBlock, LsmPgno iFirst, char **pz);
int lsmInfoArrayPages(lsm_db *pDb, LsmPgno iFirst, char **pzOut);
int lsmConfigMmap(lsm_db *pDb, int *piParam);
int lsmEnvOpen(lsm_env *, const char *, int, lsm_file **);
int lsmEnvClose(lsm_env *pEnv, lsm_file *pFile);
int lsmEnvLock(lsm_env *pEnv, lsm_file *pFile, int iLock, int eLock);
int lsmEnvTestLock(lsm_env *pEnv, lsm_file *pFile, int iLock, int nLock, int);
int lsmEnvShmMap(lsm_env *, lsm_file *, int, int, void **);
void lsmEnvShmBarrier(lsm_env *);
void lsmEnvShmUnmap(lsm_env *, lsm_file *, int);
void lsmEnvSleep(lsm_env *, int);
int lsmFsReadSyncedId(lsm_db *db, int, i64 *piVal);
int lsmFsSegmentContainsPg(FileSystem *pFS, Segment *, LsmPgno, int *);
void lsmFsPurgeCache(FileSystem *);
int lsmInfoPageDump(lsm_db *, LsmPgno, int, char **);
void lsmSortedCleanup(lsm_db *);
int lsmSortedAutoWork(lsm_db *, int nUnit);
int lsmSortedWalkFreelist(lsm_db *, int, int (*)(void *, int, i64), void *);
int lsmSaveWorker(lsm_db *, int);
int lsmFlushTreeToDisk(lsm_db *pDb);
void lsmSortedRemap(lsm_db *pDb);
void lsmSortedFreeLevel(lsm_env *pEnv, Level *);
int lsmSortedAdvanceAll(lsm_db *pDb);
int lsmSortedLoadMerge(lsm_db *, Level *, u32 *, int *);
int lsmSortedLoadFreelist(lsm_db *pDb, void **, int *);
void *lsmSortedSplitKey(Level *pLevel, int *pnByte);
void lsmSortedSaveTreeCursors(lsm_db *);
int lsmMCursorNew(lsm_db *, MultiCursor **);
void lsmMCursorClose(MultiCursor *, int);
int lsmMCursorSeek(MultiCursor *, int, void *, int , int);
int lsmMCursorFirst(MultiCursor *);
int lsmMCursorPrev(MultiCursor *);
int lsmMCursorLast(MultiCursor *);
int lsmMCursorValid(MultiCursor *);
int lsmMCursorNext(MultiCursor *);
int lsmMCursorKey(MultiCursor *, void **, int *);
int lsmMCursorValue(MultiCursor *, void **, int *);
int lsmMCursorType(MultiCursor *, int *);
lsm_db *lsmMCursorDb(MultiCursor *);
void lsmMCursorFreeCache(lsm_db *);
int lsmSaveCursors(lsm_db *pDb);
int lsmRestoreCursors(lsm_db *pDb);
void lsmSortedDumpStructure(lsm_db *pDb, Snapshot *, int, int, const char *);
void lsmFsDumpBlocklists(lsm_db *);
void lsmSortedExpandBtreePage(Page *pPg, int nOrig);
void lsmPutU32(u8 *, u32);
u32 lsmGetU32(u8 *);
u64 lsmGetU64(u8 *);
int lsmVarintPut32(u8 *, int);
int lsmVarintGet32(u8 *, int *);
int lsmVarintPut64(u8 *aData, i64 iVal);
int lsmVarintGet64(const u8 *aData, i64 *piVal);
int lsmVarintLen64(i64);
int lsmVarintLen32(int);
int lsmVarintSize(u8 c);
void lsmLogMessage(lsm_db *, int, const char *, ...);
int lsmInfoFreelist(lsm_db *pDb, char **pzOut);
int lsmLogBegin(lsm_db *pDb);
int lsmLogWrite(lsm_db *, int, void *, int, void *, int);
int lsmLogCommit(lsm_db *);
void lsmLogEnd(lsm_db *pDb, int bCommit);
void lsmLogTell(lsm_db *, LogMark *);
void lsmLogSeek(lsm_db *, LogMark *);
void lsmLogClose(lsm_db *);
int lsmLogRecover(lsm_db *);
int lsmInfoLogStructure(lsm_db *pDb, char **pzVal);
#define LSM_WRITE 0x06
#define LSM_DELETE 0x08
#define LSM_DRANGE 0x0A
int lsmDbDatabaseConnect(lsm_db*, const char *);
void lsmDbDatabaseRelease(lsm_db *);
int lsmBeginReadTrans(lsm_db *);
int lsmBeginWriteTrans(lsm_db *);
int lsmBeginFlush(lsm_db *);
int lsmDetectRoTrans(lsm_db *db, int *);
int lsmBeginRoTrans(lsm_db *db);
int lsmBeginWork(lsm_db *);
void lsmFinishWork(lsm_db *, int, int *);
int lsmFinishRecovery(lsm_db *);
void lsmFinishReadTrans(lsm_db *);
int lsmFinishWriteTrans(lsm_db *, int);
int lsmFinishFlush(lsm_db *, int);
int lsmSnapshotSetFreelist(lsm_db *, int *, int);
Snapshot *lsmDbSnapshotClient(lsm_db *);
Snapshot *lsmDbSnapshotWorker(lsm_db *);
void lsmSnapshotSetCkptid(Snapshot *, i64);
Level *lsmDbSnapshotLevel(Snapshot *);
void lsmDbSnapshotSetLevel(Snapshot *, Level *);
void lsmDbRecoveryComplete(lsm_db *, int);
int lsmBlockAllocate(lsm_db *, int, int *);
int lsmBlockFree(lsm_db *, int);
int lsmBlockRefree(lsm_db *, int);
void lsmFreelistDeltaBegin(lsm_db *);
void lsmFreelistDeltaEnd(lsm_db *);
int lsmFreelistDelta(lsm_db *pDb);
DbLog *lsmDatabaseLog(lsm_db *pDb);
#ifdef LSM_DEBUG
int lsmHoldingClientMutex(lsm_db *pDb);
int lsmShmAssertLock(lsm_db *db, int iLock, int eOp);
int lsmShmAssertWorker(lsm_db *db);
#endif
void lsmFreeSnapshot(lsm_env *, Snapshot *);
#define LSM_LOCK_UNLOCK 0
#define LSM_LOCK_SHARED 1
#define LSM_LOCK_EXCL 2
int lsmShmCacheChunks(lsm_db *db, int nChunk);
int lsmShmLock(lsm_db *db, int iLock, int eOp, int bBlock);
int lsmShmTestLock(lsm_db *db, int iLock, int nLock, int eOp);
void lsmShmBarrier(lsm_db *db);
#ifdef LSM_DEBUG
void lsmShmHasLock(lsm_db *db, int iLock, int eOp);
#else
# define lsmShmHasLock(x,y,z)
#endif
int lsmReadlock(lsm_db *, i64 iLsm, u32 iShmMin, u32 iShmMax);
int lsmLsmInUse(lsm_db *db, i64 iLsmId, int *pbInUse);
int lsmTreeInUse(lsm_db *db, u32 iLsmId, int *pbInUse);
int lsmFreelistAppend(lsm_env *pEnv, Freelist *p, int iBlk, i64 iId);
int lsmDbMultiProc(lsm_db *);
void lsmDbDeferredClose(lsm_db *, lsm_file *, LsmFile *);
LsmFile *lsmDbRecycleFd(lsm_db *);
int lsmWalkFreelist(lsm_db *, int, int (*)(void *, int, i64), void *);
int lsmCheckCompressionId(lsm_db *, u32);
void lsmStringInit(LsmString*, lsm_env *pEnv);
int lsmStringExtend(LsmString*, int);
int lsmStringAppend(LsmString*, const char *, int);
void lsmStringVAppendf(LsmString*, const char *zFormat, va_list, va_list);
void lsmStringAppendf(LsmString*, const char *zFormat, ...);
void lsmStringClear(LsmString*);
char *lsmMallocPrintf(lsm_env*, const char*, ...);
int lsmStringBinAppend(LsmString *pStr, const u8 *a, int n);
int lsmStrlen(const char *zName);
#define ROUND8(x) (((x)+7)&~7)
#define LSM_MIN(x,y) ((x)>(y) ? (y) : (x))
#define LSM_MAX(x,y) ((x)>(y) ? (x) : (y))
#endif