Further work on balance_nonroot().
FossilOrigin-Name: 6594f9b420e2fa642737722ff8521f756ecef227
This commit is contained in:
parent
09c6840153
commit
d7b545bbcb
12
manifest
12
manifest
@ -1,5 +1,5 @@
|
|||||||
C Attempt\sto\sfurther\sreduce\smemcpy()\sin\sbalance_nonroot().
|
C Further\swork\son\sbalance_nonroot().
|
||||||
D 2014-10-11T20:00:24.552
|
D 2014-10-13T18:03:27.743
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
|
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@ -172,7 +172,7 @@ F src/auth.c d8abcde53426275dab6243b441256fcd8ccbebb2
|
|||||||
F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e
|
F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e
|
||||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||||
F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5
|
F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5
|
||||||
F src/btree.c d5f4f74e309f79ace4b4025c433874ead635bed2
|
F src/btree.c 63211ca1d4ae867eede39a37901aec4746d904a7
|
||||||
F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8
|
F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8
|
||||||
F src/btreeInt.h 1bd7957161a1346a914f1f09231610e777a8e58d
|
F src/btreeInt.h 1bd7957161a1346a914f1f09231610e777a8e58d
|
||||||
F src/build.c bde83dd5cf812e310a7e5ad2846790a14745bef4
|
F src/build.c bde83dd5cf812e310a7e5ad2846790a14745bef4
|
||||||
@ -1200,7 +1200,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P 29304499ea4b72dbb6701e10cc19b5d41f7e5ac9
|
P fec849dcca3aead2bc2d4ecffeda750684d32fb0
|
||||||
R 3235ac37769ff059d7c714947e8a11dd
|
R 79e5b5564c934fc68257d82dc897cefd
|
||||||
U dan
|
U dan
|
||||||
Z 17fdfd7faf788bbb79d2ec9941c17025
|
Z ae5b74eee28666050af6baaa639de56c
|
||||||
|
@ -1 +1 @@
|
|||||||
fec849dcca3aead2bc2d4ecffeda750684d32fb0
|
6594f9b420e2fa642737722ff8521f756ecef227
|
175
src/btree.c
175
src/btree.c
@ -6009,7 +6009,7 @@ static void rebuildPage(
|
|||||||
assert( szCell[i]==cellSizePtr(pPg, pCell) );
|
assert( szCell[i]==cellSizePtr(pPg, pCell) );
|
||||||
}
|
}
|
||||||
|
|
||||||
pPg->nFree = (pData - pCellptr);
|
/* The pPg->nFree field is now set incorrectly. The caller will fix it. */
|
||||||
pPg->nCell = nCell;
|
pPg->nCell = nCell;
|
||||||
pPg->nOverflow = 0;
|
pPg->nOverflow = 0;
|
||||||
|
|
||||||
@ -6019,6 +6019,106 @@ static void rebuildPage(
|
|||||||
aData[hdr+7] = 0x00;
|
aData[hdr+7] = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u8 *pageFindSlot(MemPage *pPg, int nByte){
|
||||||
|
const int hdr = pPg->hdrOffset;
|
||||||
|
u8 * const aData = pPg->aData;
|
||||||
|
int iAddr;
|
||||||
|
int pc;
|
||||||
|
int usableSize = pPg->pBt->usableSize;
|
||||||
|
|
||||||
|
for(iAddr=hdr+1; (pc = get2byte(&aData[iAddr]))>0; iAddr=pc){
|
||||||
|
int size; /* Size of the free slot */
|
||||||
|
if( pc>usableSize-4 || pc<iAddr+4 ) return 0;
|
||||||
|
size = get2byte(&aData[pc+2]);
|
||||||
|
if( size>=nByte ){
|
||||||
|
int x = size - nByte;
|
||||||
|
testcase( x==4 );
|
||||||
|
testcase( x==3 );
|
||||||
|
if( x<4 ){
|
||||||
|
if( aData[hdr+7]>=60 ) return 0;
|
||||||
|
/* Remove the slot from the free-list. Update the number of
|
||||||
|
** fragmented bytes within the page. */
|
||||||
|
memcpy(&aData[iAddr], &aData[pc], 2);
|
||||||
|
aData[hdr+7] += (u8)x;
|
||||||
|
}else if( size+pc > usableSize ){
|
||||||
|
return 0;
|
||||||
|
}else{
|
||||||
|
/* The slot remains on the free-list. Reduce its size to account
|
||||||
|
** for the portion used by the new allocation. */
|
||||||
|
put2byte(&aData[pc+2], x);
|
||||||
|
}
|
||||||
|
return &aData[pc + x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pageInsertArray(
|
||||||
|
MemPage *pPg,
|
||||||
|
u8 *pBegin,
|
||||||
|
u8 **ppData,
|
||||||
|
u8 *pCellptr,
|
||||||
|
int nCell,
|
||||||
|
u8 **apCell, /* Array of cells */
|
||||||
|
u16 *szCell /* Array of cell sizes */
|
||||||
|
){
|
||||||
|
int i;
|
||||||
|
u8 *aData = pPg->aData;
|
||||||
|
u8 *pData = *ppData;
|
||||||
|
for(i=0; i<nCell; i++){
|
||||||
|
int sz = szCell[i];
|
||||||
|
u8 *pSlot;
|
||||||
|
if( (pSlot = pageFindSlot(pPg, sz))==0 ){
|
||||||
|
pData -= sz;
|
||||||
|
if( pData<pBegin ) return 1;
|
||||||
|
pSlot = pData;
|
||||||
|
}
|
||||||
|
memcpy(pSlot, apCell[i], sz);
|
||||||
|
put2byte(pCellptr, (pSlot - aData));
|
||||||
|
pCellptr += 2;
|
||||||
|
}
|
||||||
|
*ppData = pData;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pageFreeArray(
|
||||||
|
MemPage *pPg, /* Page to edit */
|
||||||
|
int nCell, /* Cells to delete */
|
||||||
|
u8 **apCell, /* Array of cells */
|
||||||
|
u16 *szCell /* Array of cell sizes */
|
||||||
|
){
|
||||||
|
u8 * const aData = pPg->aData;
|
||||||
|
u8 * const pEnd = &aData[pPg->pBt->usableSize];
|
||||||
|
int nRet = 0;
|
||||||
|
int i;
|
||||||
|
u8 *pFree = 0;
|
||||||
|
int szFree = 0;
|
||||||
|
|
||||||
|
for(i=0; i<nCell; i++){
|
||||||
|
u8 *pCell = apCell[i];
|
||||||
|
if( pCell>aData && pCell<pEnd ){
|
||||||
|
int sz = szCell[i];
|
||||||
|
if( pFree!=(pCell + sz) ){
|
||||||
|
if( pFree ) freeSpace(pPg, pFree - aData, szFree);
|
||||||
|
pFree = pCell;
|
||||||
|
szFree = sz;
|
||||||
|
}else{
|
||||||
|
pFree = pCell;
|
||||||
|
szFree += sz;
|
||||||
|
}
|
||||||
|
nRet++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( pFree ) freeSpace(pPg, pFree - aData, szFree);
|
||||||
|
return nRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The pPg->nFree field is invalid when this function returns. It is the
|
||||||
|
** responsibility of the caller to set it correctly.
|
||||||
|
*/
|
||||||
static void editPage(
|
static void editPage(
|
||||||
MemPage *pPg, /* Edit this page */
|
MemPage *pPg, /* Edit this page */
|
||||||
int iOld, /* Index of first cell currently on page */
|
int iOld, /* Index of first cell currently on page */
|
||||||
@ -6027,17 +6127,15 @@ static void editPage(
|
|||||||
u8 **apCell, /* Array of cells */
|
u8 **apCell, /* Array of cells */
|
||||||
u16 *szCell /* Array of cell sizes */
|
u16 *szCell /* Array of cell sizes */
|
||||||
){
|
){
|
||||||
|
|
||||||
if( 1 ){
|
|
||||||
u8 * const aData = pPg->aData;
|
u8 * const aData = pPg->aData;
|
||||||
const int hdr = pPg->hdrOffset;
|
const int hdr = pPg->hdrOffset;
|
||||||
u8 *pBegin = &pPg->aCellIdx[nNew * 2];
|
u8 *pBegin = &pPg->aCellIdx[nNew * 2];
|
||||||
int nFree = pPg->nFree; /* Free bytes on pPg */
|
|
||||||
int nCell = pPg->nCell; /* Cells stored on pPg */
|
int nCell = pPg->nCell; /* Cells stored on pPg */
|
||||||
u8 *pData;
|
u8 *pData;
|
||||||
u8 *pCellptr;
|
u8 *pCellptr;
|
||||||
int i;
|
int i;
|
||||||
int iOldEnd = iOld + pPg->nCell + pPg->nOverflow;
|
int iOldEnd = iOld + pPg->nCell + pPg->nOverflow;
|
||||||
|
int iNewEnd = iNew + nNew;
|
||||||
|
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager);
|
u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager);
|
||||||
@ -6046,40 +6144,31 @@ static void editPage(
|
|||||||
|
|
||||||
/* Remove cells from the start and end of the page */
|
/* Remove cells from the start and end of the page */
|
||||||
if( iOld<iNew ){
|
if( iOld<iNew ){
|
||||||
int nShift = 0;
|
int nShift = pageFreeArray(
|
||||||
for(i=iOld; i<iNew; i++){
|
pPg, iNew-iOld, &apCell[iOld], &szCell[iOld]
|
||||||
if( apCell[i]>aData && apCell[i]<&aData[pPg->pBt->usableSize] ){
|
);
|
||||||
freeSpace(pPg, apCell[i] - aData, szCell[i]);
|
|
||||||
nFree += szCell[i] + 2;
|
|
||||||
nShift++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nCell -= nShift;
|
|
||||||
memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
|
memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
|
||||||
|
nCell -= nShift;
|
||||||
}
|
}
|
||||||
for(i=iNew+nNew; i<iOldEnd; i++){
|
if( iNewEnd < iOldEnd ){
|
||||||
if( apCell[i]>aData && apCell[i]<&aData[pPg->pBt->usableSize] ){
|
nCell -= pageFreeArray(
|
||||||
freeSpace(pPg, apCell[i] - aData, szCell[i]);
|
pPg, iOldEnd-iNewEnd, &apCell[iNewEnd], &szCell[iNewEnd]
|
||||||
nFree += szCell[i] + 2;
|
);
|
||||||
nCell--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pData = &aData[get2byte(&aData[hdr+5])];
|
pData = &aData[get2byte(&aData[hdr+5])];
|
||||||
if( pData<pBegin ) goto editpage_fail;
|
if( pData<pBegin ) goto editpage_fail;
|
||||||
|
|
||||||
/* Add cells to the start of the page */
|
/* Add cells to the start of the page */
|
||||||
if( iNew<iOld ){
|
if( iNew<iOld ){
|
||||||
|
int nAdd = iOld-iNew;
|
||||||
pCellptr = pPg->aCellIdx;
|
pCellptr = pPg->aCellIdx;
|
||||||
memmove(&pCellptr[(iOld-iNew)*2], pCellptr, nCell*2);
|
memmove(&pCellptr[nAdd*2], pCellptr, nCell*2);
|
||||||
for(i=iNew; i<iOld; i++){
|
if( pageInsertArray(
|
||||||
pData -= szCell[i];
|
pPg, pBegin, &pData, pCellptr,
|
||||||
if( pData<pBegin ) goto editpage_fail;
|
nAdd, &apCell[iNew], &szCell[iNew]
|
||||||
memcpy(pData, apCell[i], szCell[i]);
|
) ) goto editpage_fail;
|
||||||
put2byte(pCellptr, (pData - aData));
|
nCell += nAdd;
|
||||||
pCellptr += 2;
|
|
||||||
nFree -= (szCell[i] + 2);
|
|
||||||
nCell++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add any overflow cells */
|
/* Add any overflow cells */
|
||||||
@ -6087,29 +6176,22 @@ static void editPage(
|
|||||||
int iCell = (iOld + pPg->aiOvfl[i]) - iNew;
|
int iCell = (iOld + pPg->aiOvfl[i]) - iNew;
|
||||||
if( iCell>=0 && iCell<nNew ){
|
if( iCell>=0 && iCell<nNew ){
|
||||||
u8 *pCellptr = &pPg->aCellIdx[iCell * 2];
|
u8 *pCellptr = &pPg->aCellIdx[iCell * 2];
|
||||||
int sz = szCell[iCell+iNew];
|
|
||||||
memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2);
|
memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2);
|
||||||
pData -= sz;
|
|
||||||
if( pData<pBegin ) goto editpage_fail;
|
|
||||||
memcpy(pData, apCell[iCell+iNew], sz);
|
|
||||||
put2byte(pCellptr, (pData - aData));
|
|
||||||
nFree -= (sz + 2);
|
|
||||||
nCell++;
|
nCell++;
|
||||||
|
if( pageInsertArray(
|
||||||
|
pPg, pBegin, &pData, pCellptr,
|
||||||
|
1, &apCell[iCell + iNew], &szCell[iCell + iNew]
|
||||||
|
) ) goto editpage_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append cells to the end of the page */
|
/* Append cells to the end of the page */
|
||||||
pCellptr = &pPg->aCellIdx[nCell*2];
|
pCellptr = &pPg->aCellIdx[nCell*2];
|
||||||
for(i=iNew+nCell; i<(iNew+nNew); i++){
|
if( pageInsertArray(
|
||||||
pData -= szCell[i];
|
pPg, pBegin, &pData, pCellptr,
|
||||||
if( pData<pBegin ) goto editpage_fail;
|
nNew-nCell, &apCell[iNew+nCell], &szCell[iNew+nCell]
|
||||||
memcpy(pData, apCell[i], szCell[i]);
|
) ) goto editpage_fail;
|
||||||
put2byte(pCellptr, (pData - aData));
|
|
||||||
pCellptr += 2;
|
|
||||||
nFree -= (szCell[i] + 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
pPg->nFree = nFree;
|
|
||||||
pPg->nCell = nNew;
|
pPg->nCell = nNew;
|
||||||
pPg->nOverflow = 0;
|
pPg->nOverflow = 0;
|
||||||
|
|
||||||
@ -6132,8 +6214,6 @@ static void editPage(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
editpage_fail:
|
editpage_fail:
|
||||||
#if 0
|
#if 0
|
||||||
printf("REBUILD\n");
|
printf("REBUILD\n");
|
||||||
@ -6662,7 +6742,7 @@ static int balance_nonroot(
|
|||||||
assert( i<nMaxCells );
|
assert( i<nMaxCells );
|
||||||
subtotal += szCell[i] + 2;
|
subtotal += szCell[i] + 2;
|
||||||
if( subtotal > usableSpace ){
|
if( subtotal > usableSpace ){
|
||||||
szNew[k] = subtotal - szCell[i];
|
szNew[k] = subtotal - szCell[i] - 2;
|
||||||
cntNew[k] = i;
|
cntNew[k] = i;
|
||||||
if( leafData ){ i--; }
|
if( leafData ){ i--; }
|
||||||
subtotal = 0;
|
subtotal = 0;
|
||||||
@ -7002,6 +7082,7 @@ static int balance_nonroot(
|
|||||||
|
|
||||||
editPage(apNew[iPg], iOld, iNew, nNewCell, apCell, szCell);
|
editPage(apNew[iPg], iOld, iNew, nNewCell, apCell, szCell);
|
||||||
abDone[iPg] = 1;
|
abDone[iPg] = 1;
|
||||||
|
apNew[iPg]->nFree = usableSpace-szNew[iPg];
|
||||||
assert( apNew[iPg]->nOverflow==0 );
|
assert( apNew[iPg]->nOverflow==0 );
|
||||||
assert( apNew[iPg]->nCell==nNewCell );
|
assert( apNew[iPg]->nCell==nNewCell );
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user