diff --git a/source/libs/tdb/CMakeLists.txt b/source/libs/tdb/CMakeLists.txt index aebe944630208f4c435016d6f77c86595e8a8756..978649499aa094c30bdcd6cd62ca8a00c1e86df1 100644 --- a/source/libs/tdb/CMakeLists.txt +++ b/source/libs/tdb/CMakeLists.txt @@ -8,7 +8,9 @@ target_sources(tdb "src/db/tdbBtree.c" "src/db/tdbDb.c" "src/db/tdbEnv.c" - "src/db/tdbPage.c" + # "src/db/tdbPage.c" + "src/page/tdbPage.c" + "src/page/tdbPageL.c" ) target_include_directories( diff --git a/source/libs/tdb/src/db/tdbBtree.c b/source/libs/tdb/src/db/tdbBtree.c index 55a7742f360c6d80e8595726ebce43e67273ca48..c6e8c9dca9496f1e530c1caabeee3f35ef69c1ae 100644 --- a/source/libs/tdb/src/db/tdbBtree.c +++ b/source/libs/tdb/src/db/tdbBtree.c @@ -96,11 +96,11 @@ int tdbBtreeOpen(int keyLen, int valLen, SPager *pPager, FKeyComparator kcmpr, S // pBt->pageSize pBt->pageSize = tdbPagerGetPageSize(pPager); // pBt->maxLocal - pBt->maxLocal = (pBt->pageSize - sizeof(SPageHdr)) / pBt->fanout; + pBt->maxLocal = (pBt->pageSize - 14) / pBt->fanout; // pBt->minLocal: Should not be allowed smaller than 15, which is [nPayload][nKey][nData] - pBt->minLocal = (pBt->pageSize - sizeof(SPageHdr)) / pBt->fanout / 2; + pBt->minLocal = (pBt->pageSize - 14) / pBt->fanout / 2; // pBt->maxLeaf - pBt->maxLeaf = pBt->pageSize - sizeof(SPageHdr); + pBt->maxLeaf = pBt->pageSize - 14; // pBt->minLeaf pBt->minLeaf = pBt->minLocal; @@ -392,9 +392,9 @@ static int tdbBtreeInitPage(SPage *pPage, void *arg) { pPage->szAmHdr = sizeof(SBtPageHdr); } pPage->pPageHdr = pPage->pData; - pPage->pAmHdr = pPage->pPageHdr + pPage->szPageHdr; + pPage->pAmHdr = pPage->pPageHdr + pPage->pPageMethods->szPageHdr; pPage->pCellIdx = pPage->pAmHdr + pPage->szAmHdr; - pPage->pFreeStart = pPage->pCellIdx + pPage->szOffset * TDB_PAGE_NCELLS(pPage); + pPage->pFreeStart = pPage->pCellIdx + pPage->pPageMethods->szOffset * TDB_PAGE_NCELLS(pPage); pPage->pFreeEnd = pPage->pData + TDB_PAGE_CCELLS(pPage); pPage->pPageFtr = (SPageFtr *)(pPage->pData + pPage->pageSize - sizeof(SPageFtr)); @@ -458,8 +458,8 @@ static int tdbBtreeCopyPageContent(SPage *pFrom, SPage *pTo) { int fCell = TDB_PAGE_FCELL(pFrom); int nFree = TDB_PAGE_NFREE(pFrom); - pTo->pFreeStart = pTo->pCellIdx + nCells * pFrom->szOffset; - memcpy(pTo->pCellIdx, pFrom->pCellIdx, nCells * pFrom->szOffset); + pTo->pFreeStart = pTo->pCellIdx + nCells * pFrom->pPageMethods->szOffset; + memcpy(pTo->pCellIdx, pFrom->pCellIdx, nCells * pFrom->pPageMethods->szOffset); pTo->pFreeEnd = (u8 *)pTo->pPageFtr - (u8 *)(pFrom->pPageFtr) + pFrom->pFreeEnd; memcpy(pTo->pFreeEnd, pFrom->pFreeEnd, (u8 *)pFrom->pPageFtr - pFrom->pFreeEnd); diff --git a/source/libs/tdb/src/inc/tdbPage.h b/source/libs/tdb/src/inc/tdbPage.h index f7f03375b39e142da242892eaa7c9a8d501fdc6a..edda97d3c798cacb71d4860a10232940e83cc85f 100644 --- a/source/libs/tdb/src/inc/tdbPage.h +++ b/source/libs/tdb/src/inc/tdbPage.h @@ -22,23 +22,30 @@ extern "C" { typedef u8 SCell; -// Page header (pageSize < 65536 (64K)) -typedef struct __attribute__((__packed__)) { - u16 flags; - u16 nCells; // number of cells - u16 cCells; // cell content offset - u16 fCell; // first free cell offset - u16 nFree; // total fragment bytes in this page -} SPageHdr; - -// Large page header (pageSize >= 65536 (64K)) -typedef struct __attribute__((__packed__)) { - u16 flags; - u8 nCells[3]; - u8 cCells[3]; - u8 fCell[3]; - u8 nFree[3]; -} SPageHdrL; +// PAGE APIS implemented +typedef struct { + int szOffset; + int szPageHdr; + int szFreeCell; + // flags + u16 (*getFlags)(SPage *); + void (*setFlags)(SPage *, u16); + // cell number + int (*getCellNum)(SPage *); + void (*setCellNum)(SPage *, int); + // cell content offset + int (*getCellBody)(SPage *); + void (*setCellBody)(SPage *, int); + // first free cell offset (0 means no free cells) + int (*getCellFree)(SPage *); + void (*setCellFree)(SPage *, int); + // total free bytes + int (*getFreeBytes)(SPage *); + void (*setFreeBytes)(SPage *, int); + // cell offset at idx + int (*getCellOffset)(SPage *, int); + void (*setCellOffset)(SPage *, int, int); +} SPageMethods; // Page footer typedef struct __attribute__((__packed__)) { @@ -49,9 +56,7 @@ struct SPage { pthread_spinlock_t lock; u8 *pData; int pageSize; - u8 szOffset; - u8 szPageHdr; - u8 szFreeCell; + SPageMethods *pPageMethods; // Fields below used by pager and am u8 szAmHdr; u8 *pPageHdr; @@ -72,101 +77,22 @@ struct SPage { TDB_PCACHE_PAGE }; -// Macros -#define TDB_IS_LARGE_PAGE(pPage) ((pPage)->szOffset == 3) - -/* For small page */ -#define TDB_SPAGE_FLAGS(pPage) (((SPageHdr *)(pPage)->pPageHdr)->flags) -#define TDB_SPAGE_NCELLS(pPage) (((SPageHdr *)(pPage)->pPageHdr)->nCells) -#define TDB_SPAGE_CCELLS(pPage) (((SPageHdr *)(pPage)->pPageHdr)->cCells) -#define TDB_SPAGE_FCELL(pPage) (((SPageHdr *)(pPage)->pPageHdr)->fCell) -#define TDB_SPAGE_NFREE(pPage) (((SPageHdr *)(pPage)->pPageHdr)->nFree) -#define TDB_SPAGE_CELL_OFFSET_AT(pPage, idx) ((u16 *)((pPage)->pCellIdx))[idx] - -#define TDB_SPAGE_FLAGS_SET(pPage, FLAGS) TDB_SPAGE_FLAGS(pPage) = (FLAGS) -#define TDB_SPAGE_NCELLS_SET(pPage, NCELLS) TDB_SPAGE_NCELLS(pPage) = (NCELLS) -#define TDB_SPAGE_CCELLS_SET(pPage, CCELLS) TDB_SPAGE_CCELLS(pPage) = (CCELLS) -#define TDB_SPAGE_FCELL_SET(pPage, FCELL) TDB_SPAGE_FCELL(pPage) = (FCELL) -#define TDB_SPAGE_NFREE_SET(pPage, NFREE) TDB_SPAGE_NFREE(pPage) = (NFREE) -#define TDB_SPAGE_CELL_OFFSET_AT_SET(pPage, idx, OFFSET) TDB_SPAGE_CELL_OFFSET_AT(pPage, idx) = (OFFSET) - -/* For large page */ -#define TDB_LPAGE_FLAGS(pPage) (((SPageHdrL *)(pPage)->pPageHdr)->flags) -#define TDB_LPAGE_NCELLS(pPage) TDB_GET_U24(((SPageHdrL *)(pPage)->pPageHdr)->nCells) -#define TDB_LPAGE_CCELLS(pPage) TDB_GET_U24(((SPageHdrL *)(pPage)->pPageHdr)->cCells) -#define TDB_LPAGE_FCELL(pPage) TDB_GET_U24(((SPageHdrL *)(pPage)->pPageHdr)->fCell) -#define TDB_LPAGE_NFREE(pPage) TDB_GET_U24(((SPageHdrL *)(pPage)->pPageHdr)->nFree) -#define TDB_LPAGE_CELL_OFFSET_AT(pPage, idx) TDB_GET_U24((pPage)->pCellIdx + idx * 3) - -#define TDB_LPAGE_FLAGS_SET(pPage, FLAGS) TDB_LPAGE_FLAGS(pPage) = (flags) -#define TDB_LPAGE_NCELLS_SET(pPage, NCELLS) TDB_PUT_U24(((SPageHdrL *)(pPage)->pPageHdr)->nCells, NCELLS) -#define TDB_LPAGE_CCELLS_SET(pPage, CCELLS) TDB_PUT_U24(((SPageHdrL *)(pPage)->pPageHdr)->cCells, CCELLS) -#define TDB_LPAGE_FCELL_SET(pPage, FCELL) TDB_PUT_U24(((SPageHdrL *)(pPage)->pPageHdr)->fCell, FCELL) -#define TDB_LPAGE_NFREE_SET(pPage, NFREE) TDB_PUT_U24(((SPageHdrL *)(pPage)->pPageHdr)->nFree, NFREE) -#define TDB_LPAGE_CELL_OFFSET_AT_SET(pPage, idx, OFFSET) TDB_PUT_U24((pPage)->pCellIdx + idx * 3, OFFSET) - /* For page */ -#define TDB_PAGE_FLAGS(pPage) (TDB_IS_LARGE_PAGE(pPage) ? TDB_LPAGE_FLAGS(pPage) : TDB_SPAGE_FLAGS(pPage)) -#define TDB_PAGE_NCELLS(pPage) (TDB_IS_LARGE_PAGE(pPage) ? TDB_LPAGE_NCELLS(pPage) : TDB_SPAGE_NCELLS(pPage)) -#define TDB_PAGE_CCELLS(pPage) (TDB_IS_LARGE_PAGE(pPage) ? TDB_LPAGE_CCELLS(pPage) : TDB_SPAGE_CCELLS(pPage)) -#define TDB_PAGE_FCELL(pPage) (TDB_IS_LARGE_PAGE(pPage) ? TDB_LPAGE_FCELL(pPage) : TDB_SPAGE_FCELL(pPage)) -#define TDB_PAGE_NFREE(pPage) (TDB_IS_LARGE_PAGE(pPage) ? TDB_LPAGE_NFREE(pPage) : TDB_SPAGE_NFREE(pPage)) -#define TDB_PAGE_CELL_OFFSET_AT(pPage, idx) \ - (TDB_IS_LARGE_PAGE(pPage) ? TDB_LPAGE_CELL_OFFSET_AT(pPage, idx) : TDB_SPAGE_CELL_OFFSET_AT(pPage, idx)) - -#define TDB_PAGE_FLAGS_SET(pPage, FLAGS) \ - do { \ - if (TDB_IS_LARGE_PAGE(pPage)) { \ - TDB_LPAGE_FLAGS_SET(pPage, FLAGS); \ - } else { \ - TDB_SPAGE_FLAGS_SET(pPage, FLAGS); \ - } \ - } while (0) - -#define TDB_PAGE_NCELLS_SET(pPage, NCELLS) \ - do { \ - if (TDB_IS_LARGE_PAGE(pPage)) { \ - TDB_LPAGE_NCELLS_SET(pPage, NCELLS); \ - } else { \ - TDB_SPAGE_NCELLS_SET(pPage, NCELLS); \ - } \ - } while (0) - -#define TDB_PAGE_CCELLS_SET(pPage, CCELLS) \ - do { \ - if (TDB_IS_LARGE_PAGE(pPage)) { \ - TDB_LPAGE_CCELLS_SET(pPage, CCELLS); \ - } else { \ - TDB_SPAGE_CCELLS_SET(pPage, CCELLS); \ - } \ - } while (0) - -#define TDB_PAGE_FCELL_SET(pPage, FCELL) \ - do { \ - if (TDB_IS_LARGE_PAGE(pPage)) { \ - TDB_LPAGE_FCELL_SET(pPage, FCELL); \ - } else { \ - TDB_SPAGE_FCELL_SET(pPage, FCELL); \ - } \ - } while (0) - -#define TDB_PAGE_NFREE_SET(pPage, NFREE) \ - do { \ - if (TDB_IS_LARGE_PAGE(pPage)) { \ - TDB_LPAGE_NFREE_SET(pPage, NFREE); \ - } else { \ - TDB_SPAGE_NFREE_SET(pPage, NFREE); \ - } \ - } while (0) - -#define TDB_PAGE_CELL_OFFSET_AT_SET(pPage, idx, OFFSET) \ - do { \ - if (TDB_IS_LARGE_PAGE(pPage)) { \ - TDB_LPAGE_CELL_OFFSET_AT_SET(pPage, idx, OFFSET); \ - } else { \ - TDB_SPAGE_CELL_OFFSET_AT_SET(pPage, idx, OFFSET); \ - } \ - } while (0) +#define TDB_PAGE_FLAGS(pPage) (*(pPage)->pPageMethods->getFlags)(pPage) +#define TDB_PAGE_NCELLS(pPage) (*(pPage)->pPageMethods->getCellNum)(pPage) +#define TDB_PAGE_CCELLS(pPage) (*(pPage)->pPageMethods->getCellBody)(pPage) +#define TDB_PAGE_FCELL(pPage) (*(pPage)->pPageMethods->getCellFree)(pPage) +#define TDB_PAGE_NFREE(pPage) (*(pPage)->pPageMethods->getFreeBytes)(pPage) +#define TDB_PAGE_CELL_OFFSET_AT(pPage, idx) (*(pPage)->pPageMethods->getCellOffset)(pPage, idx) + +#define TDB_PAGE_FLAGS_SET(pPage, FLAGS) (*(pPage)->pPageMethods->setFlags)(pPage, FLAGS) +#define TDB_PAGE_NCELLS_SET(pPage, NCELLS) (*(pPage)->pPageMethods->setCellNum)(pPage, NCELLS) +#define TDB_PAGE_CCELLS_SET(pPage, CCELLS) (*(pPage)->pPageMethods->setCellBody)(pPage, CCELLS) +#define TDB_PAGE_FCELL_SET(pPage, FCELL) (*(pPage)->pPageMethods->setCellFree)(pPage, FCELL) +#define TDB_PAGE_NFREE_SET(pPage, NFREE) (*(pPage)->pPageMethods->setFreeBytes)(pPage, NFREE) +#define TDB_PAGE_CELL_OFFSET_AT_SET(pPage, idx, OFFSET) (*(pPage)->pPageMethods->setCellOffset)(pPage, idx, OFFSET) + +#define TDB_PAGE_OFFSET_SIZE(pPage) ((pPage)->pPageMethods->szOffset) #define TDB_PAGE_CELL_AT(pPage, idx) ((pPage)->pData + TDB_PAGE_CELL_OFFSET_AT(pPage, idx)) diff --git a/source/libs/tdb/src/page/tdbPage.c b/source/libs/tdb/src/page/tdbPage.c index 3c8ba70a8da162ba151347a8b6fb21d697d01cab..4a9f309e6e2c148bd09fb08680c2a841cc20164c 100644 --- a/source/libs/tdb/src/page/tdbPage.c +++ b/source/libs/tdb/src/page/tdbPage.c @@ -31,6 +31,9 @@ typedef struct __attribute__((__packed__)) { u8 nxOffset[2]; } SFreeCell; +static int tdbPageAllocate(SPage *pPage, int size, SCell **ppCell); +static int tdbPageDefragment(SPage *pPage); + int tdbPageCreate(int pageSize, SPage **ppPage, void *(*xMalloc)(void *, size_t), void *arg) { SPage *pPage; u8 *ptr; @@ -79,7 +82,7 @@ int tdbPageInsertCell(SPage *pPage, int idx, SCell *pCell, int szCell) { u8 *pTmp; int j; - if (pPage->nOverflow || szCell + pPage->szOffset > pPage->nFree) { + if (pPage->nOverflow || szCell + TDB_PAGE_OFFSET_SIZE(pPage) > pPage->nFree) { // TODO: need to figure out if pCell may be used by outside of this function j = pPage->nOverflow++; @@ -92,8 +95,8 @@ int tdbPageInsertCell(SPage *pPage, int idx, SCell *pCell, int szCell) { } memcpy(pTarget, pCell, szCell); - pTmp = pPage->pCellIdx + idx * pPage->szOffset; - memmove(pTmp + pPage->szOffset, pTmp, pPage->pFreeStart - pTmp - pPage->szOffset); + pTmp = pPage->pCellIdx + idx * TDB_PAGE_OFFSET_SIZE(pPage); + memmove(pTmp + TDB_PAGE_OFFSET_SIZE(pPage), pTmp, pPage->pFreeStart - pTmp - TDB_PAGE_OFFSET_SIZE(pPage)); TDB_PAGE_CELL_OFFSET_AT_SET(pPage, idx, pTarget - pPage->pData); TDB_PAGE_NCELLS_SET(pPage, TDB_PAGE_NCELLS(pPage) + 1); } @@ -112,20 +115,22 @@ static int tdbPageAllocate(SPage *pPage, int size, SCell **ppCell) { u8 *pOffset; int ret; - ASSERT(pPage->nFree > size + pPage->szOffset); + ASSERT(pPage->nFree > size + TDB_PAGE_OFFSET_SIZE(pPage)); pCell = NULL; *ppCell = NULL; // 1. Try to allocate from the free space area - if (pPage->pFreeEnd - pPage->pFreeStart > size + pPage->szOffset) { + if (pPage->pFreeEnd - pPage->pFreeStart > size + TDB_PAGE_OFFSET_SIZE(pPage)) { pPage->pFreeEnd -= size; - pPage->pFreeStart += pPage->szOffset; + pPage->pFreeStart += TDB_PAGE_OFFSET_SIZE(pPage); pCell = pPage->pFreeEnd; } // 2. Try to allocate from the page free list - if ((pCell == NULL) && (pPage->pFreeEnd - pPage->pFreeStart >= pPage->szOffset) && TDB_PAGE_FCELL(pPage)) { + if ((pCell == NULL) && (pPage->pFreeEnd - pPage->pFreeStart >= TDB_PAGE_OFFSET_SIZE(pPage)) && + TDB_PAGE_FCELL(pPage)) { +#if 0 int szCell; int nxOffset; @@ -167,6 +172,7 @@ static int tdbPageAllocate(SPage *pPage, int size, SCell **ppCell) { if (pCell) { pPage->pFreeStart = pPage->pFreeStart + pPage->szOffset; } +#endif } // 3. Try to dfragment and allocate again @@ -176,18 +182,18 @@ static int tdbPageAllocate(SPage *pPage, int size, SCell **ppCell) { return -1; } - ASSERT(pPage->pFreeEnd - pPage->pFreeStart > size + pPage->szOffset); + ASSERT(pPage->pFreeEnd - pPage->pFreeStart > size + TDB_PAGE_OFFSET_SIZE(pPage)); ASSERT(pPage->nFree == pPage->pFreeEnd - pPage->pFreeStart); // Allocate from the free space area again pPage->pFreeEnd -= size; - pPage->pFreeStart += pPage->szOffset; + pPage->pFreeStart += TDB_PAGE_OFFSET_SIZE(pPage); pCell = pPage->pFreeEnd; } ASSERT(pCell != NULL); - pPage->nFree = pPage->nFree - size - pPage->szOffset; + pPage->nFree = pPage->nFree - size - TDB_PAGE_OFFSET_SIZE(pPage); *ppCell = pCell; return 0; } @@ -232,7 +238,7 @@ static inline void setPageCellFree(SPage *pPage, int cellFree) { // nFree static inline int getPageNFree(SPage *pPage) { return ((SPageHdr *)(pPage->pPageHdr))[0].nFree; } static inline void setPageNFree(SPage *pPage, int nFree) { - ASSERT(cellFree < 65536); + ASSERT(nFree < 65536); ((SPageHdr *)(pPage->pPageHdr))[0].nFree = (u16)nFree; } diff --git a/source/libs/tdb/src/page/tdbPage.h b/source/libs/tdb/src/page/tdbPage.h deleted file mode 100644 index 9170392d2385311959793c5baa7b16c8ee634509..0000000000000000000000000000000000000000 --- a/source/libs/tdb/src/page/tdbPage.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * This program is free software: you can use, redistribute, and/or modify - * it under the terms of the GNU Affero General Public License, version 3 - * or later ("AGPL"), as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#ifndef _TDB_PAGE_H_ -#define _TDB_PAGE_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef u8 SCell; - -// PAGE APIS implemented -typedef struct { - int szOffset; - int szPageHdr; - int szFreeCell; - // flags - u16 (*getFlags)(SPage *); - void (*setFlags)(SPage *, u16); - // cell number - int (*getCellNum)(SPage *); - void (*setCellNum)(SPage *, int); - // cell content offset - int (*getCellBody)(SPage *); - void (*setCellBody)(SPage *, int); - // first free cell offset (0 means no free cells) - int (*getCellFree)(SPage *); - void (*setCellFree)(SPage *, int); - // total free bytes - int (*getFreeBytes)(SPage *); - void (*setFreeBytes)(SPage *, int); - // cell offset at idx - int (*getCellOffset)(SPage *, int); - void (*setCellOffset)(SPage *, int, int); -} SPageMethods; - -// Page footer -typedef struct __attribute__((__packed__)) { - u8 cksm[4]; -} SPageFtr; - -struct SPage { - pthread_spinlock_t lock; - u8 *pData; - int pageSize; - SPageMethods *pPageMethods; - // Fields below used by pager and am - u8 szAmHdr; - u8 *pPageHdr; - u8 *pAmHdr; - u8 *pCellIdx; - u8 *pFreeStart; - u8 *pFreeEnd; - SPageFtr *pPageFtr; - int kLen; // key length of the page, -1 for unknown - int vLen; // value length of the page, -1 for unknown - int nFree; - int maxLocal; - int minLocal; - int nOverflow; - SCell *apOvfl[4]; - int aiOvfl[4]; - // Fields used by SPCache - TDB_PCACHE_PAGE -}; - -/* For page */ -#define TDB_PAGE_FLAGS(pPage) (*(pPage)->pPageMethods->getFlags)(pPage) -#define TDB_PAGE_NCELLS(pPage) (*(pPage)->pPageMethods->getCellNum)(pPage) -#define TDB_PAGE_CCELLS(pPage) (*(pPage)->pPageMethods->getCellBody)(pPage) -#define TDB_PAGE_FCELL(pPage) (*(pPage)->pPageMethods->getCellFree)(pPage) -#define TDB_PAGE_NFREE(pPage) (*(pPage)->pPageMethods->getFreeBytes)(pPage) -#define TDB_PAGE_CELL_OFFSET_AT(pPage, idx) (*(pPage)->pPageMethods->getCellOffset)(pPage, idx) - -#define TDB_PAGE_FLAGS_SET(pPage, FLAGS) (*(pPage)->pPageMethods->setFlags)(pPage, FLAGS) -#define TDB_PAGE_NCELLS_SET(pPage, NCELLS) (*(pPage)->pPageMethods->setCellNum)(pPage, NCELLS) -#define TDB_PAGE_CCELLS_SET(pPage, CCELLS) (*(pPage)->pPageMethods->setCellBody)(pPage, CCELLS) -#define TDB_PAGE_FCELL_SET(pPage, FCELL) (*(pPage)->pPageMethods->setCellFree)(pPage, FCELL) -#define TDB_PAGE_NFREE_SET(pPage, NFREE) (*(pPage)->pPageMethods->setFreeBytes)(pPage, NFREE) -#define TDB_PAGE_CELL_OFFSET_AT_SET(pPage, idx, OFFSET) (*(pPage)->pPageMethods->setCellOffset)(pPage, idx, OFFSET) - -#define TDB_PAGE_CELL_AT(pPage, idx) ((pPage)->pData + TDB_PAGE_CELL_OFFSET_AT(pPage, idx)) - -// For page lock -#define P_LOCK_SUCC 0 -#define P_LOCK_BUSY 1 -#define P_LOCK_FAIL -1 - -#define TDB_INIT_PAGE_LOCK(pPage) pthread_spin_init(&((pPage)->lock), 0) -#define TDB_DESTROY_PAGE_LOCK(pPage) pthread_spin_destroy(&((pPage)->lock)) -#define TDB_LOCK_PAGE(pPage) pthread_spin_lock(&((pPage)->lock)) -#define TDB_UNLOCK_PAGE(pPage) pthread_spin_unlock(&((pPage)->lock)) -#define TDB_TRY_LOCK_PAGE(pPage) \ - ({ \ - int ret; \ - if (pthread_spin_trylock(&((pPage)->lock)) == 0) { \ - ret = P_LOCK_SUCC; \ - } else if (errno == EBUSY) { \ - ret = P_LOCK_BUSY; \ - } else { \ - ret = P_LOCK_FAIL; \ - } \ - ret; \ - }) - -// For page ref -#define TDB_INIT_PAGE_REF(pPage) ((pPage)->nRef = 0) -#if 0 -#define TDB_REF_PAGE(pPage) (++(pPage)->nRef) -#define TDB_UNREF_PAGE(pPage) (--(pPage)->nRef) -#define TDB_GET_PAGE_REF(pPage) ((pPage)->nRef) -#else -#define TDB_REF_PAGE(pPage) atomic_add_fetch_32(&((pPage)->nRef), 1) -#define TDB_UNREF_PAGE(pPage) atomic_sub_fetch_32(&((pPage)->nRef), 1) -#define TDB_GET_PAGE_REF(pPage) atomic_load_32(&((pPage)->nRef)) -#endif - -// APIs -int tdbPageCreate(int pageSize, SPage **ppPage, void *(*xMalloc)(void *, size_t), void *arg); -int tdbPageDestroy(SPage *pPage, void (*xFree)(void *arg, void *ptr), void *arg); -int tdbPageInsertCell(SPage *pPage, int idx, SCell *pCell, int szCell); -int tdbPageDropCell(SPage *pPage, int idx); - -#ifdef __cplusplus -} -#endif - -#endif /*_TDB_PAGE_H_*/ \ No newline at end of file