refact TDB to support meta
This commit is contained in:
parent
98fc272ac8
commit
13740e8988
|
@ -42,8 +42,7 @@ struct SBTree {
|
|||
ASSERT(TDB_FLAG_IS(flags, TDB_BTREE_ROOT) || TDB_FLAG_IS(flags, TDB_BTREE_LEAF) || \
|
||||
TDB_FLAG_IS(flags, TDB_BTREE_ROOT | TDB_BTREE_LEAF) || TDB_FLAG_IS(flags, 0))
|
||||
|
||||
|
||||
#pragma pack(push,1)
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
TDB_BTREE_PAGE_COMMON_HDR
|
||||
} SLeafHdr;
|
||||
|
@ -71,8 +70,7 @@ typedef struct {
|
|||
static int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst);
|
||||
static int tdbDefaultKeyCmprFn(const void *pKey1, int keyLen1, const void *pKey2, int keyLen2);
|
||||
static int tdbBtreeOpenImpl(SBTree *pBt);
|
||||
static int tdbBtreeZeroPage(SPage *pPage, void *arg);
|
||||
static int tdbBtreeInitPage(SPage *pPage, void *arg);
|
||||
static int tdbBtreeInitPage(SPage *pPage, void *arg, int init);
|
||||
static int tdbBtreeEncodeCell(SPage *pPage, const void *pKey, int kLen, const void *pVal, int vLen, SCell *pCell,
|
||||
int *szCell);
|
||||
static int tdbBtreeDecodeCell(SPage *pPage, const SCell *pCell, SCellDecoder *pDecoder);
|
||||
|
@ -312,75 +310,57 @@ static int tdbBtreeOpenImpl(SBTree *pBt) {
|
|||
}
|
||||
|
||||
// Try to create a new database
|
||||
SBtreeInitPageArg zArg = {.flags = TDB_BTREE_ROOT | TDB_BTREE_LEAF, .pBt = pBt};
|
||||
ret = tdbPagerNewPage(pBt->pPager, &pgno, &pPage, tdbBtreeZeroPage, &zArg, NULL);
|
||||
ret = tdbPagerAllocPage(pBt->pPager, &pgno);
|
||||
if (ret < 0) {
|
||||
ASSERT(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO: here still has problem
|
||||
tdbPagerReturnPage(pBt->pPager, pPage, NULL);
|
||||
|
||||
ASSERT(pgno != 0);
|
||||
pBt->root = pgno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tdbBtreeInitPage(SPage *pPage, void *arg) {
|
||||
static int tdbBtreeInitPage(SPage *pPage, void *arg, int init) {
|
||||
SBTree *pBt;
|
||||
u8 flags;
|
||||
u8 isLeaf;
|
||||
|
||||
pBt = (SBTree *)arg;
|
||||
flags = TDB_BTREE_PAGE_GET_FLAGS(pPage);
|
||||
isLeaf = TDB_BTREE_PAGE_IS_LEAF(pPage);
|
||||
|
||||
ASSERT(flags == TDB_BTREE_PAGE_GET_FLAGS(pPage));
|
||||
|
||||
tdbPageInit(pPage, isLeaf ? sizeof(SLeafHdr) : sizeof(SIntHdr), tdbBtreeCellSize);
|
||||
|
||||
TDB_BTREE_ASSERT_FLAG(flags);
|
||||
|
||||
if (isLeaf) {
|
||||
pPage->kLen = pBt->keyLen;
|
||||
pPage->vLen = pBt->valLen;
|
||||
pPage->maxLocal = pBt->maxLeaf;
|
||||
pPage->minLocal = pBt->minLeaf;
|
||||
} else {
|
||||
pPage->kLen = pBt->keyLen;
|
||||
pPage->vLen = sizeof(SPgno);
|
||||
pPage->maxLocal = pBt->maxLocal;
|
||||
pPage->minLocal = pBt->minLocal;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tdbBtreeZeroPage(SPage *pPage, void *arg) {
|
||||
u8 flags;
|
||||
SBTree *pBt;
|
||||
u8 leaf;
|
||||
|
||||
flags = ((SBtreeInitPageArg *)arg)->flags;
|
||||
pBt = ((SBtreeInitPageArg *)arg)->pBt;
|
||||
leaf = flags & TDB_BTREE_LEAF;
|
||||
|
||||
tdbPageZero(pPage, leaf ? sizeof(SLeafHdr) : sizeof(SIntHdr), tdbBtreeCellSize);
|
||||
if (init) {
|
||||
// init page
|
||||
flags = TDB_BTREE_PAGE_GET_FLAGS(pPage);
|
||||
leaf = TDB_BTREE_PAGE_IS_LEAF(pPage);
|
||||
TDB_BTREE_ASSERT_FLAG(flags);
|
||||
|
||||
tdbPageInit(pPage, leaf ? sizeof(SLeafHdr) : sizeof(SIntHdr), tdbBtreeCellSize);
|
||||
} else {
|
||||
// zero page
|
||||
flags = ((SBtreeInitPageArg *)arg)->flags;
|
||||
leaf = flags & TDB_BTREE_LEAF;
|
||||
TDB_BTREE_ASSERT_FLAG(flags);
|
||||
|
||||
tdbPageZero(pPage, leaf ? sizeof(SLeafHdr) : sizeof(SIntHdr), tdbBtreeCellSize);
|
||||
|
||||
if (leaf) {
|
||||
SLeafHdr *pLeafHdr = (SLeafHdr *)(pPage->pData);
|
||||
pLeafHdr->flags = flags;
|
||||
|
||||
} else {
|
||||
SIntHdr *pIntHdr = (SIntHdr *)(pPage->pData);
|
||||
pIntHdr->flags = flags;
|
||||
pIntHdr->pgno = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (leaf) {
|
||||
SLeafHdr *pLeafHdr = (SLeafHdr *)(pPage->pData);
|
||||
pLeafHdr->flags = flags;
|
||||
|
||||
pPage->kLen = pBt->keyLen;
|
||||
pPage->vLen = pBt->valLen;
|
||||
pPage->maxLocal = pBt->maxLeaf;
|
||||
pPage->minLocal = pBt->minLeaf;
|
||||
} else {
|
||||
SIntHdr *pIntHdr = (SIntHdr *)(pPage->pData);
|
||||
pIntHdr->flags = flags;
|
||||
pIntHdr->pgno = 0;
|
||||
|
||||
pPage->kLen = pBt->keyLen;
|
||||
pPage->vLen = sizeof(SPgno);
|
||||
pPage->maxLocal = pBt->maxLocal;
|
||||
|
@ -405,10 +385,11 @@ static int tdbBtreeBalanceDeeper(SBTree *pBt, SPage *pRoot, SPage **ppChild, TXN
|
|||
flags = TDB_BTREE_PAGE_GET_FLAGS(pRoot);
|
||||
leaf = TDB_BTREE_PAGE_IS_LEAF(pRoot);
|
||||
|
||||
// Allocate a new child page
|
||||
// allocate a new child page
|
||||
pgnoChild = 0;
|
||||
zArg.flags = TDB_FLAG_REMOVE(flags, TDB_BTREE_ROOT);
|
||||
zArg.pBt = pBt;
|
||||
ret = tdbPagerNewPage(pPager, &pgnoChild, &pChild, tdbBtreeZeroPage, &zArg, pTxn);
|
||||
ret = tdbPagerFetchPage(pPager, &pgnoChild, &pChild, tdbBtreeInitPage, &zArg, pTxn);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -430,7 +411,7 @@ static int tdbBtreeBalanceDeeper(SBTree *pBt, SPage *pRoot, SPage **ppChild, TXN
|
|||
// Reinitialize the root page
|
||||
zArg.flags = TDB_BTREE_ROOT;
|
||||
zArg.pBt = pBt;
|
||||
ret = tdbBtreeZeroPage(pRoot, &zArg);
|
||||
ret = tdbBtreeInitPage(pRoot, &zArg, 0);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -483,7 +464,8 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
|
|||
pgno = *(SPgno *)pCell;
|
||||
}
|
||||
|
||||
ret = tdbPagerFetchPage(pBt->pPager, pgno, pOlds + i, tdbBtreeInitPage, pBt, pTxn);
|
||||
ret = tdbPagerFetchPage(pBt->pPager, &pgno, pOlds + i, tdbBtreeInitPage,
|
||||
&((SBtreeInitPageArg){.pBt = pBt, .flags = 0}), pTxn);
|
||||
if (ret < 0) {
|
||||
ASSERT(0);
|
||||
return -1;
|
||||
|
@ -644,9 +626,10 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
|
|||
if (iNew < nOlds) {
|
||||
pNews[iNew] = pOlds[iNew];
|
||||
} else {
|
||||
pgno = 0;
|
||||
iarg.pBt = pBt;
|
||||
iarg.flags = flags;
|
||||
ret = tdbPagerNewPage(pBt->pPager, &pgno, pNews + iNew, tdbBtreeZeroPage, &iarg, pTxn);
|
||||
ret = tdbPagerFetchPage(pBt->pPager, &pgno, pNews + iNew, tdbBtreeInitPage, &iarg, pTxn);
|
||||
if (ret < 0) {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
@ -674,13 +657,13 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
|
|||
iarg.pBt = pBt;
|
||||
iarg.flags = TDB_BTREE_PAGE_GET_FLAGS(pOlds[0]);
|
||||
for (int i = 0; i < nOlds; i++) {
|
||||
tdbPageCreate(pOlds[0]->pageSize, &pOldsCopy[i], NULL, NULL);
|
||||
tdbBtreeZeroPage(pOldsCopy[i], &iarg);
|
||||
tdbPageCreate(pOlds[0]->pageSize, &pOldsCopy[i], tdbDefaultMalloc, NULL);
|
||||
tdbBtreeInitPage(pOldsCopy[i], &iarg, 0);
|
||||
tdbPageCopy(pOlds[i], pOldsCopy[i]);
|
||||
}
|
||||
iNew = 0;
|
||||
nNewCells = 0;
|
||||
tdbBtreeZeroPage(pNews[iNew], &iarg);
|
||||
tdbBtreeInitPage(pNews[iNew], &iarg, 0);
|
||||
|
||||
for (int iOld = 0; iOld < nOlds; iOld++) {
|
||||
SPage *pPage;
|
||||
|
@ -721,7 +704,7 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
|
|||
iNew++;
|
||||
nNewCells = 0;
|
||||
if (iNew < nNews) {
|
||||
tdbBtreeZeroPage(pNews[iNew], &iarg);
|
||||
tdbBtreeInitPage(pNews[iNew], &iarg, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -740,7 +723,7 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
|
|||
iNew++;
|
||||
nNewCells = 0;
|
||||
if (iNew < nNews) {
|
||||
tdbBtreeZeroPage(pNews[iNew], &iarg);
|
||||
tdbBtreeInitPage(pNews[iNew], &iarg, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -760,7 +743,7 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
|
|||
}
|
||||
|
||||
for (int i = 0; i < nOlds; i++) {
|
||||
tdbPageDestroy(pOldsCopy[i], NULL, NULL);
|
||||
tdbPageDestroy(pOldsCopy[i], tdbDefaultFree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1035,7 +1018,13 @@ int tdbBtcOpen(SBTC *pBtc, SBTree *pBt, TXN *pTxn) {
|
|||
pBtc->iPage = -1;
|
||||
pBtc->pPage = NULL;
|
||||
pBtc->idx = -1;
|
||||
pBtc->pTxn = pTxn;
|
||||
|
||||
if (pTxn == NULL) {
|
||||
pBtc->pTxn = &pBtc->txn;
|
||||
tdbTxnOpen(pBtc->pTxn, 0, tdbDefaultMalloc, tdbDefaultFree, NULL, 0);
|
||||
} else {
|
||||
pBtc->pTxn = pTxn;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1052,7 +1041,8 @@ int tdbBtcMoveToFirst(SBTC *pBtc) {
|
|||
|
||||
if (pBtc->iPage < 0) {
|
||||
// move a clean cursor
|
||||
ret = tdbPagerFetchPage(pPager, pBt->root, &(pBtc->pPage), tdbBtreeInitPage, pBt, pBtc->pTxn);
|
||||
ret = tdbPagerFetchPage(pPager, &pBt->root, &(pBtc->pPage), tdbBtreeInitPage,
|
||||
&((SBtreeInitPageArg){.pBt = pBt, .flags = 0}), pBtc->pTxn);
|
||||
if (ret < 0) {
|
||||
ASSERT(0);
|
||||
return -1;
|
||||
|
@ -1117,7 +1107,8 @@ int tdbBtcMoveToLast(SBTC *pBtc) {
|
|||
|
||||
if (pBtc->iPage < 0) {
|
||||
// move a clean cursor
|
||||
ret = tdbPagerFetchPage(pPager, pBt->root, &(pBtc->pPage), tdbBtreeInitPage, pBt, pBtc->pTxn);
|
||||
ret = tdbPagerFetchPage(pPager, &pBt->root, &(pBtc->pPage), tdbBtreeInitPage,
|
||||
&((SBtreeInitPageArg){.pBt = pBt, .flags = 0}), pBtc->pTxn);
|
||||
if (ret < 0) {
|
||||
ASSERT(0);
|
||||
return -1;
|
||||
|
@ -1286,13 +1277,16 @@ static int tdbBtcMoveDownward(SBTC *pBtc) {
|
|||
pgno = ((SIntHdr *)pBtc->pPage->pData)->pgno;
|
||||
}
|
||||
|
||||
ASSERT(pgno);
|
||||
|
||||
pBtc->pgStack[pBtc->iPage] = pBtc->pPage;
|
||||
pBtc->idxStack[pBtc->iPage] = pBtc->idx;
|
||||
pBtc->iPage++;
|
||||
pBtc->pPage = NULL;
|
||||
pBtc->idx = -1;
|
||||
|
||||
ret = tdbPagerFetchPage(pBtc->pBt->pPager, pgno, &pBtc->pPage, tdbBtreeInitPage, pBtc->pBt, pBtc->pTxn);
|
||||
ret = tdbPagerFetchPage(pBtc->pBt->pPager, &pgno, &pBtc->pPage, tdbBtreeInitPage,
|
||||
&((SBtreeInitPageArg){.pBt = pBtc->pBt, .flags = 0}), pBtc->pTxn);
|
||||
if (ret < 0) {
|
||||
ASSERT(0);
|
||||
return -1;
|
||||
|
@ -1327,7 +1321,8 @@ static int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
|
|||
|
||||
if (pBtc->iPage < 0) {
|
||||
// move from a clear cursor
|
||||
ret = tdbPagerFetchPage(pPager, pBt->root, &(pBtc->pPage), tdbBtreeInitPage, pBt, pBtc->pTxn);
|
||||
ret = tdbPagerFetchPage(pPager, &pBt->root, &(pBtc->pPage), tdbBtreeInitPage,
|
||||
&((SBtreeInitPageArg){.pBt = pBt, .flags = TDB_BTREE_ROOT | TDB_BTREE_LEAF}), pBtc->pTxn);
|
||||
if (ret < 0) {
|
||||
// TODO
|
||||
ASSERT(0);
|
||||
|
|
|
@ -95,6 +95,8 @@ SPage *tdbPCacheFetch(SPCache *pCache, const SPgid *pPgid, TXN *pTxn) {
|
|||
void tdbPCacheRelease(SPCache *pCache, SPage *pPage, TXN *pTxn) {
|
||||
i32 nRef;
|
||||
|
||||
ASSERT(pTxn);
|
||||
|
||||
nRef = TDB_UNREF_PAGE(pPage);
|
||||
ASSERT(nRef >= 0);
|
||||
|
||||
|
@ -108,8 +110,10 @@ void tdbPCacheRelease(SPCache *pCache, SPage *pPage, TXN *pTxn) {
|
|||
if (pPage->isLocal) {
|
||||
tdbPCacheUnpinPage(pCache, pPage);
|
||||
} else {
|
||||
// remove from hash
|
||||
tdbPCacheRemovePageFromHash(pCache, pPage);
|
||||
if (TDB_TXN_IS_WRITE(pTxn)) {
|
||||
// remove from hash
|
||||
tdbPCacheRemovePageFromHash(pCache, pPage);
|
||||
}
|
||||
|
||||
// free the page
|
||||
if (pTxn && pTxn->xFree) {
|
||||
|
@ -125,8 +129,11 @@ void tdbPCacheRelease(SPCache *pCache, SPage *pPage, TXN *pTxn) {
|
|||
int tdbPCacheGetPageSize(SPCache *pCache) { return pCache->pageSize; }
|
||||
|
||||
static SPage *tdbPCacheFetchImpl(SPCache *pCache, const SPgid *pPgid, TXN *pTxn) {
|
||||
int ret;
|
||||
SPage *pPage;
|
||||
int ret = 0;
|
||||
SPage *pPage = NULL;
|
||||
SPage *pPageH = NULL;
|
||||
|
||||
ASSERT(pTxn);
|
||||
|
||||
// 1. Search the hash table
|
||||
pPage = pCache->pgHash[tdbPCachePageHash(pPgid) % pCache->nHash];
|
||||
|
@ -136,12 +143,17 @@ static SPage *tdbPCacheFetchImpl(SPCache *pCache, const SPgid *pPgid, TXN *pTxn)
|
|||
}
|
||||
|
||||
if (pPage) {
|
||||
// TODO: the page need to be copied and
|
||||
// replaced the page in hash table
|
||||
tdbPCachePinPage(pCache, pPage);
|
||||
return pPage;
|
||||
if (pPage->isLocal || TDB_TXN_IS_WRITE(pTxn)) {
|
||||
tdbPCachePinPage(pCache, pPage);
|
||||
return pPage;
|
||||
}
|
||||
}
|
||||
|
||||
// 1. pPage == NULL
|
||||
// 2. pPage && pPage->isLocal == 0 && !TDB_TXN_IS_WRITE(pTxn)
|
||||
pPageH = pPage;
|
||||
pPage = NULL;
|
||||
|
||||
// 2. Try to allocate a new page from the free list
|
||||
if (pCache->pFree) {
|
||||
pPage = pCache->pFree;
|
||||
|
@ -158,7 +170,7 @@ static SPage *tdbPCacheFetchImpl(SPCache *pCache, const SPgid *pPgid, TXN *pTxn)
|
|||
}
|
||||
|
||||
// 4. Try a create new page
|
||||
if (!pPage && pTxn && pTxn->xMalloc) {
|
||||
if (!pPage) {
|
||||
ret = tdbPageCreate(pCache->pageSize, &pPage, pTxn->xMalloc, pTxn->xArg);
|
||||
if (ret < 0) {
|
||||
// TODO
|
||||
|
@ -176,12 +188,22 @@ static SPage *tdbPCacheFetchImpl(SPCache *pCache, const SPgid *pPgid, TXN *pTxn)
|
|||
// or by recycling or allocated streesly,
|
||||
// need to initialize it
|
||||
if (pPage) {
|
||||
memcpy(&(pPage->pgid), pPgid, sizeof(*pPgid));
|
||||
pPage->pLruNext = NULL;
|
||||
pPage->pPager = NULL;
|
||||
if (pPageH) {
|
||||
// copy the page content
|
||||
memcpy(&(pPage->pgid), pPgid, sizeof(*pPgid));
|
||||
pPage->pLruNext = NULL;
|
||||
pPage->pPager = pPageH->pPager;
|
||||
|
||||
// TODO: allocated page may not add to hash
|
||||
tdbPCacheAddPageToHash(pCache, pPage);
|
||||
memcpy(pPage->pData, pPageH->pData, pPage->pageSize);
|
||||
} else {
|
||||
memcpy(&(pPage->pgid), pPgid, sizeof(*pPgid));
|
||||
pPage->pLruNext = NULL;
|
||||
pPage->pPager = NULL;
|
||||
|
||||
if (pPage->isLocal || TDB_TXN_IS_WRITE(pTxn)) {
|
||||
tdbPCacheAddPageToHash(pCache, pPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pPage;
|
||||
|
@ -249,7 +271,7 @@ static int tdbPCacheOpenImpl(SPCache *pCache) {
|
|||
pCache->nFree = 0;
|
||||
pCache->pFree = NULL;
|
||||
for (int i = 0; i < pCache->cacheSize; i++) {
|
||||
ret = tdbPageCreate(pCache->pageSize, &pPage, NULL, NULL);
|
||||
ret = tdbPageCreate(pCache->pageSize, &pPage, tdbDefaultMalloc, NULL);
|
||||
if (ret < 0) {
|
||||
// TODO: handle error
|
||||
return -1;
|
||||
|
|
|
@ -43,15 +43,14 @@ int tdbPageCreate(int pageSize, SPage **ppPage, void *(*xMalloc)(void *, size_t)
|
|||
u8 *ptr;
|
||||
int size;
|
||||
|
||||
ASSERT(xMalloc);
|
||||
|
||||
ASSERT(TDB_IS_PGSIZE_VLD(pageSize));
|
||||
|
||||
*ppPage = NULL;
|
||||
size = pageSize + sizeof(*pPage);
|
||||
if (xMalloc == NULL) {
|
||||
xMalloc = tdbDefaultMalloc;
|
||||
}
|
||||
|
||||
ptr = (u8 *)((*xMalloc)(arg, size));
|
||||
ptr = (u8 *)(xMalloc(arg, size));
|
||||
if (ptr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -75,12 +74,10 @@ int tdbPageCreate(int pageSize, SPage **ppPage, void *(*xMalloc)(void *, size_t)
|
|||
int tdbPageDestroy(SPage *pPage, void (*xFree)(void *arg, void *ptr), void *arg) {
|
||||
u8 *ptr;
|
||||
|
||||
if (!xFree) {
|
||||
xFree = tdbDefaultFree;
|
||||
}
|
||||
ASSERT(xFree);
|
||||
|
||||
ptr = pPage->pData;
|
||||
(*xFree)(arg, ptr);
|
||||
xFree(arg, ptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -436,7 +433,7 @@ static int tdbPageDefragment(SPage *pPage) {
|
|||
|
||||
/* ---------------------------------------------------------------------------------------------------------- */
|
||||
|
||||
#pragma pack(push,1)
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
u16 cellNum;
|
||||
u16 cellBody;
|
||||
|
@ -520,7 +517,7 @@ SPageMethods pageMethods = {
|
|||
setPageFreeCellInfo // setFreeCellInfo
|
||||
};
|
||||
|
||||
#pragma pack(push,1)
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
u8 cellNum[3];
|
||||
u8 cellBody[3];
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include "tdbInt.h"
|
||||
|
||||
#pragma pack(push,1)
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
u8 hdrString[16];
|
||||
u16 pageSize;
|
||||
|
@ -29,7 +29,8 @@ TDB_STATIC_ASSERT(sizeof(SFileHdr) == 128, "Size of file header is not correct")
|
|||
|
||||
#define TDB_PAGE_INITIALIZED(pPage) ((pPage)->pPager != NULL)
|
||||
|
||||
static int tdbPagerInitPage(SPager *pPager, SPage *pPage, int (*initPage)(SPage *, void *), void *arg, u8 loadPage);
|
||||
static int tdbPagerInitPage(SPager *pPager, SPage *pPage, int (*initPage)(SPage *, void *, int), void *arg,
|
||||
u8 loadPage);
|
||||
static int tdbPagerWritePageToJournal(SPager *pPager, SPage *pPage);
|
||||
static int tdbPagerWritePageToDB(SPager *pPager, SPage *pPage);
|
||||
|
||||
|
@ -228,13 +229,30 @@ int tdbPagerCommit(SPager *pPager, TXN *pTxn) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tdbPagerFetchPage(SPager *pPager, SPgno pgno, SPage **ppPage, int (*initPage)(SPage *, void *), void *arg,
|
||||
int tdbPagerFetchPage(SPager *pPager, SPgno *ppgno, SPage **ppPage, int (*initPage)(SPage *, void *, int), void *arg,
|
||||
TXN *pTxn) {
|
||||
SPage *pPage;
|
||||
SPgid pgid;
|
||||
int ret;
|
||||
SPgno pgno;
|
||||
u8 loadPage;
|
||||
|
||||
// Fetch a page container from the page cache
|
||||
pgno = *ppgno;
|
||||
loadPage = 1;
|
||||
|
||||
// alloc new page
|
||||
if (pgno == 0) {
|
||||
loadPage = 0;
|
||||
ret = tdbPagerAllocPage(pPager, &pgno);
|
||||
if (ret < 0) {
|
||||
ASSERT(0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(pgno > 0);
|
||||
|
||||
// fetch a page container
|
||||
memcpy(&pgid, pPager->fid, TDB_FILE_ID_LEN);
|
||||
pgid.pgno = pgno;
|
||||
pPage = tdbPCacheFetch(pPager->pCache, &pgid, pTxn);
|
||||
|
@ -242,9 +260,9 @@ int tdbPagerFetchPage(SPager *pPager, SPgno pgno, SPage **ppPage, int (*initPage
|
|||
return -1;
|
||||
}
|
||||
|
||||
// Initialize the page if need
|
||||
// init page if need
|
||||
if (!TDB_PAGE_INITIALIZED(pPage)) {
|
||||
ret = tdbPagerInitPage(pPager, pPage, initPage, arg, 1);
|
||||
ret = tdbPagerInitPage(pPager, pPage, initPage, arg, loadPage);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -253,46 +271,7 @@ int tdbPagerFetchPage(SPager *pPager, SPgno pgno, SPage **ppPage, int (*initPage
|
|||
ASSERT(TDB_PAGE_INITIALIZED(pPage));
|
||||
ASSERT(pPage->pPager == pPager);
|
||||
|
||||
*ppPage = pPage;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tdbPagerNewPage(SPager *pPager, SPgno *ppgno, SPage **ppPage, int (*initPage)(SPage *, void *), void *arg,
|
||||
TXN *pTxn) {
|
||||
int ret;
|
||||
SPage *pPage;
|
||||
SPgid pgid;
|
||||
|
||||
// Allocate a page number
|
||||
ret = tdbPagerAllocPage(pPager, ppgno);
|
||||
if (ret < 0) {
|
||||
ASSERT(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ASSERT(*ppgno != 0);
|
||||
|
||||
// Fetch a page container from the page cache
|
||||
memcpy(&pgid, pPager->fid, TDB_FILE_ID_LEN);
|
||||
pgid.pgno = *ppgno;
|
||||
pPage = tdbPCacheFetch(pPager->pCache, &pgid, pTxn);
|
||||
if (pPage == NULL) {
|
||||
ASSERT(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ASSERT(!TDB_PAGE_INITIALIZED(pPage));
|
||||
|
||||
// Initialize the page if need
|
||||
ret = tdbPagerInitPage(pPager, pPage, initPage, arg, 0);
|
||||
if (ret < 0) {
|
||||
ASSERT(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ASSERT(TDB_PAGE_INITIALIZED(pPage));
|
||||
ASSERT(pPage->pPager == pPager);
|
||||
|
||||
*ppgno = pgno;
|
||||
*ppPage = pPage;
|
||||
return 0;
|
||||
}
|
||||
|
@ -333,11 +312,14 @@ int tdbPagerAllocPage(SPager *pPager, SPgno *ppgno) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tdbPagerInitPage(SPager *pPager, SPage *pPage, int (*initPage)(SPage *, void *), void *arg, u8 loadPage) {
|
||||
int ret;
|
||||
int lcode;
|
||||
int nLoops;
|
||||
i64 nRead;
|
||||
static int tdbPagerInitPage(SPager *pPager, SPage *pPage, int (*initPage)(SPage *, void *, int), void *arg,
|
||||
u8 loadPage) {
|
||||
int ret;
|
||||
int lcode;
|
||||
int nLoops;
|
||||
i64 nRead;
|
||||
SPgno pgno;
|
||||
int init = 0;
|
||||
|
||||
lcode = TDB_TRY_LOCK_PAGE(pPage);
|
||||
if (lcode == P_LOCK_SUCC) {
|
||||
|
@ -346,20 +328,21 @@ static int tdbPagerInitPage(SPager *pPager, SPage *pPage, int (*initPage)(SPage
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (loadPage) {
|
||||
nRead = tdbOsPRead(pPager->fd, pPage->pData, pPage->pageSize, ((i64)pPage->pageSize) * TDB_PAGE_PGNO(pPage));
|
||||
if (nRead < 0) {
|
||||
// TODO
|
||||
ASSERT(0);
|
||||
return -1;
|
||||
} else if (nRead < pPage->pageSize) {
|
||||
// TODO
|
||||
pgno = TDB_PAGE_PGNO(pPage);
|
||||
|
||||
if (loadPage && pgno <= pPager->dbOrigSize) {
|
||||
init = 1;
|
||||
|
||||
nRead = tdbOsPRead(pPager->fd, pPage->pData, pPage->pageSize, ((i64)pPage->pageSize) * pgno);
|
||||
if (nRead < pPage->pageSize) {
|
||||
ASSERT(0);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
init = 0;
|
||||
}
|
||||
|
||||
ret = (*initPage)(pPage, arg);
|
||||
ret = (*initPage)(pPage, arg, init);
|
||||
if (ret < 0) {
|
||||
TDB_UNLOCK_PAGE(pPage);
|
||||
return -1;
|
||||
|
|
|
@ -36,6 +36,7 @@ struct SBTC {
|
|||
int idxStack[BTREE_MAX_DEPTH + 1];
|
||||
SPage *pgStack[BTREE_MAX_DEPTH + 1];
|
||||
TXN *pTxn;
|
||||
TXN txn;
|
||||
};
|
||||
|
||||
// SBTree
|
||||
|
|
|
@ -42,10 +42,8 @@ int tdbPagerOpenDB(SPager *pPager, SPgno *ppgno, bool toCreate);
|
|||
int tdbPagerWrite(SPager *pPager, SPage *pPage);
|
||||
int tdbPagerBegin(SPager *pPager, TXN *pTxn);
|
||||
int tdbPagerCommit(SPager *pPager, TXN *pTxn);
|
||||
int tdbPagerFetchPage(SPager *pPager, SPgno pgno, SPage **ppPage, int (*initPage)(SPage *, void *), void *arg,
|
||||
int tdbPagerFetchPage(SPager *pPager, SPgno *ppgno, SPage **ppPage, int (*initPage)(SPage *, void *, int), void *arg,
|
||||
TXN *pTxn);
|
||||
int tdbPagerNewPage(SPager *pPager, SPgno *ppgno, SPage **ppPage, int (*initPage)(SPage *, void *), void *arg,
|
||||
TXN *pTxn);
|
||||
void tdbPagerReturnPage(SPager *pPager, SPage *pPage, TXN *pTxn);
|
||||
int tdbPagerAllocPage(SPager *pPager, SPgno *ppgno);
|
||||
|
||||
|
|
Loading…
Reference in New Issue