more TDB
This commit is contained in:
parent
d7b54201bc
commit
3b49a863ea
|
@ -564,7 +564,7 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx) {
|
||||||
if (infoNews[nNews].size + cellBytes > TDB_PAGE_USABLE_SIZE(pPage)) {
|
if (infoNews[nNews].size + cellBytes > TDB_PAGE_USABLE_SIZE(pPage)) {
|
||||||
// page is full, use a new page
|
// page is full, use a new page
|
||||||
nNews++;
|
nNews++;
|
||||||
// for a internal leaf case, this cell is used as the new divider cell to parent
|
// for an internal leaf case, this cell is used as the new divider cell to parent
|
||||||
if (!childLeaf) continue;
|
if (!childLeaf) continue;
|
||||||
}
|
}
|
||||||
infoNews[nNews].cnt++;
|
infoNews[nNews].cnt++;
|
||||||
|
@ -594,10 +594,10 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx) {
|
||||||
int nCells;
|
int nCells;
|
||||||
int cellBytes;
|
int cellBytes;
|
||||||
|
|
||||||
if (childLeaf) { // child leaf
|
pPage = pOlds[infoNews[iNew - 1].oPage];
|
||||||
pPage = pOlds[infoNews[iNew - 1].oPage];
|
nCells = TDB_PAGE_TOTAL_CELLS(pPage);
|
||||||
nCells = TDB_PAGE_TOTAL_CELLS(pPage);
|
|
||||||
|
|
||||||
|
if (childLeaf) { // child leaf
|
||||||
for (;;) {
|
for (;;) {
|
||||||
pCell = tdbPageGetCell(pPage, infoNews[iNew - 1].oIdx);
|
pCell = tdbPageGetCell(pPage, infoNews[iNew - 1].oIdx);
|
||||||
cellBytes = TDB_BYTES_CELL_TAKEN(pPage, pCell);
|
cellBytes = TDB_BYTES_CELL_TAKEN(pPage, pCell);
|
||||||
|
@ -618,7 +618,55 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // internal leaf
|
} else { // internal leaf
|
||||||
// TODO
|
SCell *pCellRight;
|
||||||
|
SCell *pCellLeft;
|
||||||
|
int szCellRight, szCellLeft;
|
||||||
|
|
||||||
|
// get pCellLeft, szCellLeft
|
||||||
|
if (infoNews[iNew - 1].oIdx == nCells) {
|
||||||
|
ASSERT(infoNews[iNew - 1].oPage < nOlds - 1);
|
||||||
|
pCellLeft = pDivCell[infoNews[iNew - 1].oPage];
|
||||||
|
szCellLeft = szDivCell[infoNews[iNew - 1].oPage];
|
||||||
|
} else {
|
||||||
|
pCellLeft = tdbPageGetCell(pPage, infoNews[iNew - 1].oIdx);
|
||||||
|
szCellLeft = tdbBtreeCellSize(pPage, pCellLeft);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get pCellRight, szCellRight
|
||||||
|
if (infoNews[iNew - 1].oIdx + 1 < nCells) {
|
||||||
|
pCellRight = tdbPageGetCell(pPage, infoNews[iNew - 1].oIdx + 1);
|
||||||
|
szCellRight = tdbBtreeCellSize(pPage, pCellRight);
|
||||||
|
} else {
|
||||||
|
if (infoNews[iNew - 1].oPage < nOlds - 1) {
|
||||||
|
pCellRight = pDivCell[infoNews[iNew - 1].oPage];
|
||||||
|
szCellRight = szDivCell[infoNews[iNew - 1].oPage];
|
||||||
|
} else {
|
||||||
|
// TODO: what if the next old page is empty?
|
||||||
|
pCellRight = tdbPageGetCell(pOlds[infoNews[iNew - 1].oPage + 1], 0);
|
||||||
|
szCellRight = tdbBtreeCellSize(pPage, pCellRight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (infoNews[iNew - 1].size - szCellLeft - TDB_PAGE_OFFSET_SIZE(pPage) <=
|
||||||
|
infoNews[iNew].size + szCellRight + TDB_PAGE_OFFSET_SIZE(pPage)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: ASSERT(infoNews[iNew].size < PAGE_MAX_CAPACITY);
|
||||||
|
infoNews[iNew].cnt++;
|
||||||
|
infoNews[iNew].size += szCellRight;
|
||||||
|
infoNews[iNew - 1].cnt--;
|
||||||
|
infoNews[iNew - 1].size -= szCellLeft;
|
||||||
|
if ((infoNews[iNew - 1].oIdx--) == 0) {
|
||||||
|
infoNews[iNew - 1].oPage--;
|
||||||
|
pPage = pOlds[infoNews[iNew - 1].oPage];
|
||||||
|
nCells = TDB_PAGE_TOTAL_CELLS(pPage);
|
||||||
|
if (infoNews[iNew - 1].oPage < nOlds - 1) {
|
||||||
|
infoNews[iNew - 1].oIdx = nCells;
|
||||||
|
} else {
|
||||||
|
infoNews[iNew - 1].oIdx = nCells - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -654,6 +702,8 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx) {
|
||||||
int tPage, tIdx, iOld;
|
int tPage, tIdx, iOld;
|
||||||
SCell *pCell;
|
SCell *pCell;
|
||||||
int szCell;
|
int szCell;
|
||||||
|
int nCells;
|
||||||
|
SCellDecoder cd;
|
||||||
SBtreeInitPageArg iarg = {.flags = TDB_BTREE_PAGE_GET_FLAGS(pOlds[0]), .pBt = pBt};
|
SBtreeInitPageArg iarg = {.flags = TDB_BTREE_PAGE_GET_FLAGS(pOlds[0]), .pBt = pBt};
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
|
@ -666,28 +716,117 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx) {
|
||||||
tPage = 0;
|
tPage = 0;
|
||||||
tIdx = 0;
|
tIdx = 0;
|
||||||
iOld = 0;
|
iOld = 0;
|
||||||
|
nCells = TDB_PAGE_TOTAL_CELLS(pOlds[iOld]);
|
||||||
tdbBtreeZeroPage(pTPage[tPage], &iarg);
|
tdbBtreeZeroPage(pTPage[tPage], &iarg);
|
||||||
tdbPageCopy(pOlds[iOld++], pTPage[tPage]);
|
tdbPageCopy(pOlds[iOld], pTPage[tPage]);
|
||||||
|
if (!childLeaf) {
|
||||||
|
((SIntHdr *)pTPage[tPage]->pData)->pgno = ((SIntHdr *)pOlds[iOld]->pData)->pgno;
|
||||||
|
}
|
||||||
|
|
||||||
for (int iNew = 0; iNew < nNews; iNew++) {
|
for (int iNew = 0; iNew < nNews; iNew++) {
|
||||||
// fill the iNew page
|
// fill the iNew page
|
||||||
|
// TODO: copy current page to tmp space
|
||||||
tdbBtreeZeroPage(pNews[iNew], &iarg);
|
tdbBtreeZeroPage(pNews[iNew], &iarg);
|
||||||
|
|
||||||
for (int iCell = 0; iCell < infoNews[iNew].cnt; iCell++) {
|
for (int iCell = 0; iCell < infoNews[iNew].cnt; iCell++) {
|
||||||
while (tIdx >= TDB_PAGE_TOTAL_CELLS(pTPage[tPage])) {
|
for (;;) { // loop to find the next available cell
|
||||||
tPage = (tPage + 1) % 2;
|
if (tIdx < nCells) {
|
||||||
tIdx = 0;
|
pCell = tdbPageGetCell(pTPage[tPage], tIdx);
|
||||||
|
szCell = tdbBtreeCellSize(pTPage[tPage], pCell);
|
||||||
|
tIdx++;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if (!childLeaf) {
|
||||||
|
if (iOld < nOlds - 1) {
|
||||||
|
pCell = pDivCell[iOld];
|
||||||
|
szCell = szDivCell[iOld];
|
||||||
|
((SPgno *)pCell)[0] = ((SIntHdr *)pOlds[iOld]->pData)->pgno;
|
||||||
|
|
||||||
tdbBtreeZeroPage(pTPage[tPage], &iarg);
|
iOld++;
|
||||||
tdbPageCopy(pOlds[iOld++], pTPage[tPage]);
|
tPage = (tPage + 1) % 2;
|
||||||
|
tIdx = 0;
|
||||||
|
nCells = TDB_PAGE_TOTAL_CELLS(pOlds[iOld]);
|
||||||
|
tdbBtreeZeroPage(pTPage[tPage], &iarg);
|
||||||
|
tdbPageCopy(pOlds[iOld], pTPage[tPage]);
|
||||||
|
((SIntHdr *)pTPage[tPage]->pData)->pgno = ((SIntHdr *)pOlds[iOld]->pData)->pgno;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
iOld++;
|
||||||
|
tPage = (tPage + 1) % 2;
|
||||||
|
tIdx = 0;
|
||||||
|
nCells = TDB_PAGE_TOTAL_CELLS(pOlds[iOld]);
|
||||||
|
tdbBtreeZeroPage(pTPage[tPage], &iarg);
|
||||||
|
tdbPageCopy(pOlds[iOld], pTPage[tPage]);
|
||||||
|
((SIntHdr *)pTPage[tPage]->pData)->pgno = ((SIntHdr *)pOlds[iOld]->pData)->pgno;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
iOld++;
|
||||||
|
tPage = (tPage + 1) % 2;
|
||||||
|
tIdx = 0;
|
||||||
|
nCells = TDB_PAGE_TOTAL_CELLS(pOlds[iOld]);
|
||||||
|
tdbBtreeZeroPage(pTPage[tPage], &iarg);
|
||||||
|
tdbPageCopy(pOlds[iOld], pTPage[tPage]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pCell = tdbPageGetCell(pTPage[tPage], tIdx);
|
|
||||||
szCell = tdbBtreeCellSize(pTPage[tPage], pCell);
|
|
||||||
|
|
||||||
tdbPageInsertCell(pNews[iNew], iCell, pCell, szCell);
|
tdbPageInsertCell(pNews[iNew], iCell, pCell, szCell);
|
||||||
|
}
|
||||||
|
|
||||||
tIdx++;
|
// fill right-most child pgno if internal page
|
||||||
|
if (!childLeaf) {
|
||||||
|
if (tIdx < nCells) {
|
||||||
|
pCell = tdbPageGetCell(pTPage[tPage], tIdx);
|
||||||
|
szCell = tdbBtreeCellSize(pTPage[tPage], pCell);
|
||||||
|
tIdx++;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if (!childLeaf) {
|
||||||
|
if (iOld < nOlds - 1) {
|
||||||
|
pCell = pDivCell[iOld];
|
||||||
|
szCell = szDivCell[iOld];
|
||||||
|
((SPgno *)pCell)[0] = ((SIntHdr *)pOlds[iOld]->pData)->pgno;
|
||||||
|
|
||||||
|
iOld++;
|
||||||
|
tPage = (tPage + 1) % 2;
|
||||||
|
tIdx = 0;
|
||||||
|
nCells = TDB_PAGE_TOTAL_CELLS(pOlds[iOld]);
|
||||||
|
tdbBtreeZeroPage(pTPage[tPage], &iarg);
|
||||||
|
tdbPageCopy(pOlds[iOld], pTPage[tPage]);
|
||||||
|
((SIntHdr *)pTPage[tPage]->pData)->pgno = ((SIntHdr *)pOlds[iOld]->pData)->pgno;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
iOld++;
|
||||||
|
tPage = (tPage + 1) % 2;
|
||||||
|
tIdx = 0;
|
||||||
|
nCells = TDB_PAGE_TOTAL_CELLS(pOlds[iOld]);
|
||||||
|
tdbBtreeZeroPage(pTPage[tPage], &iarg);
|
||||||
|
tdbPageCopy(pOlds[iOld], pTPage[tPage]);
|
||||||
|
((SIntHdr *)pTPage[tPage]->pData)->pgno = ((SIntHdr *)pOlds[iOld]->pData)->pgno;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
iOld++;
|
||||||
|
tPage = (tPage + 1) % 2;
|
||||||
|
tIdx = 0;
|
||||||
|
nCells = TDB_PAGE_TOTAL_CELLS(pOlds[iOld]);
|
||||||
|
tdbBtreeZeroPage(pTPage[tPage], &iarg);
|
||||||
|
tdbPageCopy(pOlds[iOld], pTPage[tPage]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
((SIntHdr *)pNews[iNew]->pData)->pgno = ((SPgno *)pCell)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert divider cell into the parent page
|
||||||
|
SIntHdr *pIntHdr = (SIntHdr *)pParent->pData;
|
||||||
|
if (iNew == nNews - 1 && pIntHdr->pgno == 0) {
|
||||||
|
pIntHdr->pgno = TDB_PAGE_PGNO(pNews[iNew]);
|
||||||
|
} else {
|
||||||
|
tdbBtreeDecodeCell(pNews[iNew], tdbPageGetCell(pNews[iNew], TDB_PAGE_TOTAL_CELLS(pNews[iNew]) - 1), &cd);
|
||||||
|
tdbBtreeEncodeCell(pParent, cd.pKey, cd.kLen, (void *)&TDB_PAGE_PGNO(pNews[iNew]), sizeof(SPgno), pCell,
|
||||||
|
&szCell);
|
||||||
|
// TODO: the cell here may be used by pParent as an overflow cell
|
||||||
|
tdbPageInsertCell(pParent, sIdx++, pCell, szCell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,31 +835,6 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Insert records in parent page
|
|
||||||
int cIdx = sIdx;
|
|
||||||
int szCell;
|
|
||||||
SCell pCell[128]; // TODO
|
|
||||||
SCellDecoder cd;
|
|
||||||
|
|
||||||
for (int iNew = 0; iNew < nNews; iNew++) {
|
|
||||||
if (iNew == nNews - 1) {
|
|
||||||
// The last new page
|
|
||||||
|
|
||||||
SIntHdr *pIntHdr = (SIntHdr *)pParent->pData;
|
|
||||||
if (pIntHdr->pgno == 0) {
|
|
||||||
pIntHdr->pgno = TDB_PAGE_PGNO(pNews[iNew]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tdbBtreeDecodeCell(pNews[iNew], tdbPageGetCell(pNews[iNew], TDB_PAGE_TOTAL_CELLS(pNews[iNew]) - 1), &cd);
|
|
||||||
|
|
||||||
tdbBtreeEncodeCell(pParent, cd.pKey, cd.kLen, (void *)&TDB_PAGE_PGNO(pNews[iNew]), sizeof(SPgno), pCell, &szCell);
|
|
||||||
// TODO: the cell here may be used by pParent as an overflow cell
|
|
||||||
tdbPageInsertCell(pParent, cIdx, pCell, szCell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue