more TDB
This commit is contained in:
parent
6fa90a9142
commit
3c044ef262
|
@ -15,7 +15,13 @@
|
||||||
|
|
||||||
#include "tdbInt.h"
|
#include "tdbInt.h"
|
||||||
|
|
||||||
|
typedef struct __attribute__((__packed__)) {
|
||||||
|
u16 size;
|
||||||
|
u16 nOffset;
|
||||||
|
} SFreeCell;
|
||||||
|
|
||||||
static int tdbPageAllocate(SPage *pPage, int size, SCell **ppCell);
|
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) {
|
int tdbPageCreate(int pageSize, SPage **ppPage, void *(*xMalloc)(void *, size_t), void *arg) {
|
||||||
SPage *pPage;
|
SPage *pPage;
|
||||||
|
@ -66,7 +72,7 @@ int tdbPageInsertCell(SPage *pPage, int idx, SCell *pCell, int szCell) {
|
||||||
SCell *pTarget;
|
SCell *pTarget;
|
||||||
|
|
||||||
if (pPage->nOverflow || szCell + pPage->szOffset > pPage->nFree) {
|
if (pPage->nOverflow || szCell + pPage->szOffset > pPage->nFree) {
|
||||||
// TODO
|
// TODO: Page is full
|
||||||
} else {
|
} else {
|
||||||
ret = tdbPageAllocate(pPage, szCell, &pTarget);
|
ret = tdbPageAllocate(pPage, szCell, &pTarget);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -87,18 +93,63 @@ int tdbPageDropCell(SPage *pPage, int idx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tdbPageAllocate(SPage *pPage, int size, SCell **ppCell) {
|
static int tdbPageAllocate(SPage *pPage, int size, SCell **ppCell) {
|
||||||
SCell *pCell;
|
SCell *pCell;
|
||||||
|
SFreeCell *pFreeCell;
|
||||||
|
int ret;
|
||||||
|
|
||||||
ASSERT(pPage->nFree > size + pPage->szOffset);
|
ASSERT(pPage->nFree > size + pPage->szOffset);
|
||||||
|
|
||||||
|
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 + pPage->szOffset) {
|
||||||
pPage->pFreeEnd -= size;
|
pPage->pFreeEnd -= size;
|
||||||
pPage->pFreeStart += pPage->szOffset;
|
pPage->pFreeStart += pPage->szOffset;
|
||||||
|
|
||||||
pCell = pPage->pFreeEnd;
|
pCell = pPage->pFreeEnd;
|
||||||
} else {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2. Try to allocate from the page free list
|
||||||
|
if (pCell == NULL && TDB_PAGE_FCELL(pPage)) {
|
||||||
|
pCell = pPage->pData + TDB_PAGE_FCELL(pPage);
|
||||||
|
for (;;) {
|
||||||
|
pFreeCell = (SFreeCell *)pCell;
|
||||||
|
|
||||||
|
if (pFreeCell->size >= size) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pFreeCell->nOffset) {
|
||||||
|
pCell = pPage->pData + pFreeCell->nOffset;
|
||||||
|
} else {
|
||||||
|
pCell = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Try to dfragment
|
||||||
|
if (pCell == NULL) {
|
||||||
|
ret = tdbPageDefragment(pPage);
|
||||||
|
if (ret < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(pPage->pFreeEnd - pPage->pFreeStart > size + pPage->szOffset);
|
||||||
|
ASSERT(pPage->nFree == pPage->pFreeEnd - pPage->pFreeStart);
|
||||||
|
|
||||||
|
// Allocate from the free space area again
|
||||||
|
pPage->pFreeEnd -= size;
|
||||||
|
pPage->pFreeStart += pPage->szOffset;
|
||||||
|
pCell = pPage->pFreeEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(pCell != NULL);
|
||||||
|
|
||||||
|
pPage->nFree = pPage->nFree - size - pPage->szOffset;
|
||||||
*ppCell = pCell;
|
*ppCell = pCell;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,10 @@ typedef u8 SCell;
|
||||||
// Page header (pageSize < 65536 (64K))
|
// Page header (pageSize < 65536 (64K))
|
||||||
typedef struct __attribute__((__packed__)) {
|
typedef struct __attribute__((__packed__)) {
|
||||||
u16 flags;
|
u16 flags;
|
||||||
u16 nCells;
|
u16 nCells; // number of cells
|
||||||
u16 cCells;
|
u16 cCells; // cell content offset
|
||||||
u16 fCell;
|
u16 fCell; // first free cell offset
|
||||||
u16 nFree;
|
u16 nFree; // total fragment bytes in this page
|
||||||
} SPageHdr;
|
} SPageHdr;
|
||||||
|
|
||||||
// Large page header (pageSize >= 65536 (64K))
|
// Large page header (pageSize >= 65536 (64K))
|
||||||
|
|
Loading…
Reference in New Issue