mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Change the way that balance_nonroot() partitions cells between the sibling
pages such that a scan of the cell size array is not required. FossilOrigin-Name: 168728715156d756ac8c0df45710d054eee027ec
This commit is contained in:
15
manifest
15
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Update\sthe\sfuzztest\sdata\susing\sthe\slatest\stest\svectors\sdiscovered\sby\sAFL.
|
C Change\sthe\sway\sthat\sbalance_nonroot()\spartitions\scells\sbetween\sthe\ssibling\npages\ssuch\sthat\sa\sscan\sof\sthe\scell\ssize\sarray\sis\snot\srequired.
|
||||||
D 2015-06-20T14:11:56.166
|
D 2015-06-22T20:02:04.079
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 1063c58075b7400d93326b0eb332b48a54f53025
|
F Makefile.in 1063c58075b7400d93326b0eb332b48a54f53025
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -192,7 +192,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
|||||||
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
|
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
|
||||||
F src/bitvec.c 5eb7958c3bf65210211cbcfc44eff86d0ded7c9d
|
F src/bitvec.c 5eb7958c3bf65210211cbcfc44eff86d0ded7c9d
|
||||||
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
||||||
F src/btree.c 173c2ba1b8cf941971683f584965369791125f12
|
F src/btree.c 8f65725c7c138aecb1a6339ef2b276b4b3632a20
|
||||||
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
||||||
F src/btreeInt.h 6ece2dd9c8e2eac05f0a8ded8772a44e96486c65
|
F src/btreeInt.h 6ece2dd9c8e2eac05f0a8ded8772a44e96486c65
|
||||||
F src/build.c b3f15255d5b16e42dafeaa638fd4f8a47c94ed70
|
F src/build.c b3f15255d5b16e42dafeaa638fd4f8a47c94ed70
|
||||||
@@ -1286,7 +1286,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P 7cdbae625eb029538a693d2bebec465a6f65fb90
|
P b97f9cf73e503c7285ba3a801e1f932f222d96b2
|
||||||
R 5add07a39efb3611e2cfa0ac20a2c5f5
|
R d9f18f053d77ccfca6ce052159dd7203
|
||||||
|
T *branch * btree-opt2
|
||||||
|
T *sym-btree-opt2 *
|
||||||
|
T -sym-trunk *
|
||||||
U drh
|
U drh
|
||||||
Z 71db4d574368380e4b14cadc01f6d8d0
|
Z ffa77b78cbb43ac17ffd24e89fe96b6a
|
||||||
|
@@ -1 +1 @@
|
|||||||
b97f9cf73e503c7285ba3a801e1f932f222d96b2
|
168728715156d756ac8c0df45710d054eee027ec
|
81
src/btree.c
81
src/btree.c
@@ -3206,6 +3206,7 @@ static int setChildPtrmaps(MemPage *pPage){
|
|||||||
if( !pPage->leaf ){
|
if( !pPage->leaf ){
|
||||||
Pgno childPgno = get4byte(pCell);
|
Pgno childPgno = get4byte(pCell);
|
||||||
ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc);
|
ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc);
|
||||||
|
if( rc ) return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6295,7 +6296,7 @@ static void insertCell(
|
|||||||
** The MemPage.nFree field is invalidated by this function. It is the
|
** The MemPage.nFree field is invalidated by this function. It is the
|
||||||
** responsibility of the caller to set it correctly.
|
** responsibility of the caller to set it correctly.
|
||||||
*/
|
*/
|
||||||
static void rebuildPage(
|
static int rebuildPage(
|
||||||
MemPage *pPg, /* Edit this page */
|
MemPage *pPg, /* Edit this page */
|
||||||
int nCell, /* Final number of cells on page */
|
int nCell, /* Final number of cells on page */
|
||||||
u8 **apCell, /* Array of cells */
|
u8 **apCell, /* Array of cells */
|
||||||
@@ -6320,9 +6321,10 @@ static void rebuildPage(
|
|||||||
pCell = &pTmp[pCell - aData];
|
pCell = &pTmp[pCell - aData];
|
||||||
}
|
}
|
||||||
pData -= szCell[i];
|
pData -= szCell[i];
|
||||||
memcpy(pData, pCell, szCell[i]);
|
|
||||||
put2byte(pCellptr, (pData - aData));
|
put2byte(pCellptr, (pData - aData));
|
||||||
pCellptr += 2;
|
pCellptr += 2;
|
||||||
|
if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT;
|
||||||
|
memcpy(pData, pCell, szCell[i]);
|
||||||
assert( szCell[i]==pPg->xCellSize(pPg, pCell) || CORRUPT_DB );
|
assert( szCell[i]==pPg->xCellSize(pPg, pCell) || CORRUPT_DB );
|
||||||
testcase( szCell[i]==pPg->xCellSize(pPg,pCell) );
|
testcase( szCell[i]==pPg->xCellSize(pPg,pCell) );
|
||||||
}
|
}
|
||||||
@@ -6335,6 +6337,7 @@ static void rebuildPage(
|
|||||||
put2byte(&aData[hdr+3], pPg->nCell);
|
put2byte(&aData[hdr+3], pPg->nCell);
|
||||||
put2byte(&aData[hdr+5], pData - aData);
|
put2byte(&aData[hdr+5], pData - aData);
|
||||||
aData[hdr+7] = 0x00;
|
aData[hdr+7] = 0x00;
|
||||||
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6454,7 +6457,7 @@ static int pageFreeArray(
|
|||||||
** The pPg->nFree field is invalid when this function returns. It is the
|
** The pPg->nFree field is invalid when this function returns. It is the
|
||||||
** responsibility of the caller to set it correctly.
|
** responsibility of the caller to set it correctly.
|
||||||
*/
|
*/
|
||||||
static void editPage(
|
static int 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 */
|
||||||
int iNew, /* Index of new first cell on page */
|
int iNew, /* Index of new first cell on page */
|
||||||
@@ -6545,10 +6548,10 @@ static void editPage(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return;
|
return SQLITE_OK;
|
||||||
editpage_fail:
|
editpage_fail:
|
||||||
/* Unable to edit this page. Rebuild it from scratch instead. */
|
/* Unable to edit this page. Rebuild it from scratch instead. */
|
||||||
rebuildPage(pPg, nNew, &apCell[iNew], &szCell[iNew]);
|
return rebuildPage(pPg, nNew, &apCell[iNew], &szCell[iNew]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6620,7 +6623,8 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
|
|||||||
assert( sqlite3PagerIswriteable(pNew->pDbPage) );
|
assert( sqlite3PagerIswriteable(pNew->pDbPage) );
|
||||||
assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) );
|
assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) );
|
||||||
zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF);
|
zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF);
|
||||||
rebuildPage(pNew, 1, &pCell, &szCell);
|
rc = rebuildPage(pNew, 1, &pCell, &szCell);
|
||||||
|
if( rc ) return rc;
|
||||||
pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell;
|
pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell;
|
||||||
|
|
||||||
/* If this is an auto-vacuum database, update the pointer map
|
/* If this is an auto-vacuum database, update the pointer map
|
||||||
@@ -6835,7 +6839,6 @@ static int balance_nonroot(
|
|||||||
int leafData; /* True if pPage is a leaf of a LEAFDATA tree */
|
int leafData; /* True if pPage is a leaf of a LEAFDATA tree */
|
||||||
int usableSpace; /* Bytes in pPage beyond the header */
|
int usableSpace; /* Bytes in pPage beyond the header */
|
||||||
int pageFlags; /* Value of pPage->aData[0] */
|
int pageFlags; /* Value of pPage->aData[0] */
|
||||||
int subtotal; /* Subtotal of bytes in cells on one page */
|
|
||||||
int iSpace1 = 0; /* First unused byte of aSpace1[] */
|
int iSpace1 = 0; /* First unused byte of aSpace1[] */
|
||||||
int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */
|
int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */
|
||||||
int szScratch; /* Size of scratch memory requested */
|
int szScratch; /* Size of scratch memory requested */
|
||||||
@@ -7081,21 +7084,50 @@ static int balance_nonroot(
|
|||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
usableSpace = pBt->usableSize - 12 + leafCorrection;
|
usableSpace = pBt->usableSize - 12 + leafCorrection;
|
||||||
for(subtotal=k=i=0; i<nCell; i++){
|
for(i=0; i<nOld; i++){
|
||||||
assert( i<nMaxCells );
|
MemPage *p = apOld[i];
|
||||||
subtotal += szCell[i] + 2;
|
szNew[i] = usableSpace - p->nFree;
|
||||||
if( subtotal > usableSpace ){
|
if( szNew[i]<0 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; }
|
||||||
szNew[k] = subtotal - szCell[i] - 2;
|
for(j=0; j<p->nOverflow; j++){
|
||||||
cntNew[k] = i;
|
szNew[i] += 2 + p->xCellSize(p, p->apOvfl[j]);
|
||||||
if( leafData ){ i--; }
|
}
|
||||||
subtotal = 0;
|
cntNew[i] = cntOld[i];
|
||||||
k++;
|
}
|
||||||
if( k>NB+1 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; }
|
k = nOld;
|
||||||
|
for(i=0; i<k; i++){
|
||||||
|
int sz;
|
||||||
|
while( szNew[i]>usableSpace ){
|
||||||
|
if( i+1>=k ){
|
||||||
|
k = i+2;
|
||||||
|
if( k>NB+2 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; }
|
||||||
|
szNew[k-1] = 0;
|
||||||
|
cntNew[k-1] = nCell;
|
||||||
|
}
|
||||||
|
sz = 2+szCell[cntNew[i]-1];
|
||||||
|
szNew[i] -= sz;
|
||||||
|
if( !leafData ){
|
||||||
|
sz = cntNew[i]<nCell ? 2+szCell[cntNew[i]] : 0;
|
||||||
|
}
|
||||||
|
szNew[i+1] += sz;
|
||||||
|
cntNew[i]--;
|
||||||
|
}
|
||||||
|
while( cntNew[i]<nCell ){
|
||||||
|
sz = 2+szCell[cntNew[i]];
|
||||||
|
if( szNew[i]+sz>usableSpace ) break;
|
||||||
|
szNew[i] += sz;
|
||||||
|
cntNew[i]++;
|
||||||
|
if( !leafData ){
|
||||||
|
sz = cntNew[i]<nCell ? 2+szCell[cntNew[i]] : 0;
|
||||||
|
}
|
||||||
|
szNew[i+1] -= sz;
|
||||||
|
}
|
||||||
|
if( cntNew[i]>=nCell ){
|
||||||
|
k = i+1;
|
||||||
|
}else if( cntNew[i] - (i>0 ? cntNew[i-1] : 0) <= 0 ){
|
||||||
|
rc = SQLITE_CORRUPT_BKPT;
|
||||||
|
goto balance_cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
szNew[k] = subtotal;
|
|
||||||
cntNew[k] = nCell;
|
|
||||||
k++;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The packing computed by the previous block is biased toward the siblings
|
** The packing computed by the previous block is biased toward the siblings
|
||||||
@@ -7124,6 +7156,10 @@ static int balance_nonroot(
|
|||||||
szRight += szCell[d] + 2;
|
szRight += szCell[d] + 2;
|
||||||
szLeft -= szCell[r] + 2;
|
szLeft -= szCell[r] + 2;
|
||||||
cntNew[i-1]--;
|
cntNew[i-1]--;
|
||||||
|
if( cntNew[i-1] <= 0 ){
|
||||||
|
rc = SQLITE_CORRUPT_BKPT;
|
||||||
|
goto balance_cleanup;
|
||||||
|
}
|
||||||
r = cntNew[i-1] - 1;
|
r = cntNew[i-1] - 1;
|
||||||
d = r + 1 - leafData;
|
d = r + 1 - leafData;
|
||||||
}
|
}
|
||||||
@@ -7294,9 +7330,11 @@ static int balance_nonroot(
|
|||||||
){
|
){
|
||||||
if( !leafCorrection ){
|
if( !leafCorrection ){
|
||||||
ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc);
|
ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc);
|
||||||
|
if( rc ) goto balance_cleanup;
|
||||||
}
|
}
|
||||||
if( szCell[i]>pNew->minLocal ){
|
if( szCell[i]>pNew->minLocal ){
|
||||||
ptrmapPutOvflPtr(pNew, pCell, &rc);
|
ptrmapPutOvflPtr(pNew, pCell, &rc);
|
||||||
|
if( rc ) goto balance_cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7404,7 +7442,8 @@ static int balance_nonroot(
|
|||||||
nNewCell = cntNew[iPg] - iNew;
|
nNewCell = cntNew[iPg] - iNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
editPage(apNew[iPg], iOld, iNew, nNewCell, apCell, szCell);
|
rc = editPage(apNew[iPg], iOld, iNew, nNewCell, apCell, szCell);
|
||||||
|
if( rc ) goto balance_cleanup;
|
||||||
abDone[iPg]++;
|
abDone[iPg]++;
|
||||||
apNew[iPg]->nFree = usableSpace-szNew[iPg];
|
apNew[iPg]->nFree = usableSpace-szNew[iPg];
|
||||||
assert( apNew[iPg]->nOverflow==0 );
|
assert( apNew[iPg]->nOverflow==0 );
|
||||||
|
Reference in New Issue
Block a user