From: drh Date: Mon, 22 Jun 2015 20:02:04 +0000 (+0000) Subject: Change the way that balance_nonroot() partitions cells between the sibling X-Git-Tag: version-3.8.11~142^2~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=658873bdb343e7750863b4292f53d468821c3ded;p=thirdparty%2Fsqlite.git 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 --- diff --git a/manifest b/manifest index 9332d172a2..0d513dcffa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sfuzztest\sdata\susing\sthe\slatest\stest\svectors\sdiscovered\sby\sAFL. -D 2015-06-20T14:11:56.166 +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-22T20:02:04.079 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1063c58075b7400d93326b0eb332b48a54f53025 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -192,7 +192,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3 F src/bitvec.c 5eb7958c3bf65210211cbcfc44eff86d0ded7c9d F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 -F src/btree.c 173c2ba1b8cf941971683f584965369791125f12 +F src/btree.c 8f65725c7c138aecb1a6339ef2b276b4b3632a20 F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 F src/btreeInt.h 6ece2dd9c8e2eac05f0a8ded8772a44e96486c65 F src/build.c b3f15255d5b16e42dafeaa638fd4f8a47c94ed70 @@ -1286,7 +1286,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7cdbae625eb029538a693d2bebec465a6f65fb90 -R 5add07a39efb3611e2cfa0ac20a2c5f5 +P b97f9cf73e503c7285ba3a801e1f932f222d96b2 +R d9f18f053d77ccfca6ce052159dd7203 +T *branch * btree-opt2 +T *sym-btree-opt2 * +T -sym-trunk * U drh -Z 71db4d574368380e4b14cadc01f6d8d0 +Z ffa77b78cbb43ac17ffd24e89fe96b6a diff --git a/manifest.uuid b/manifest.uuid index ad06e9f3b1..49c14f7000 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b97f9cf73e503c7285ba3a801e1f932f222d96b2 \ No newline at end of file +168728715156d756ac8c0df45710d054eee027ec \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index e64139b800..ad86c36e78 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3206,6 +3206,7 @@ static int setChildPtrmaps(MemPage *pPage){ if( !pPage->leaf ){ Pgno childPgno = get4byte(pCell); 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 ** responsibility of the caller to set it correctly. */ -static void rebuildPage( +static int rebuildPage( MemPage *pPg, /* Edit this page */ int nCell, /* Final number of cells on page */ u8 **apCell, /* Array of cells */ @@ -6320,9 +6321,10 @@ static void rebuildPage( pCell = &pTmp[pCell - aData]; } pData -= szCell[i]; - memcpy(pData, pCell, szCell[i]); put2byte(pCellptr, (pData - aData)); pCellptr += 2; + if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT; + memcpy(pData, pCell, szCell[i]); assert( szCell[i]==pPg->xCellSize(pPg, pCell) || CORRUPT_DB ); testcase( szCell[i]==pPg->xCellSize(pPg,pCell) ); } @@ -6335,6 +6337,7 @@ static void rebuildPage( put2byte(&aData[hdr+3], pPg->nCell); put2byte(&aData[hdr+5], pData - aData); 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 ** responsibility of the caller to set it correctly. */ -static void editPage( +static int editPage( MemPage *pPg, /* Edit this page */ int iOld, /* Index of first cell currently on page */ int iNew, /* Index of new first cell on page */ @@ -6545,10 +6548,10 @@ static void editPage( } #endif - return; + return SQLITE_OK; editpage_fail: /* 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( pPage->aData[0]==(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; /* 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 usableSpace; /* Bytes in pPage beyond the header */ 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 iOvflSpace = 0; /* First unused byte of aOvflSpace[] */ int szScratch; /* Size of scratch memory requested */ @@ -7081,21 +7084,50 @@ static int balance_nonroot( ** */ usableSpace = pBt->usableSize - 12 + leafCorrection; - for(subtotal=k=i=0; i usableSpace ){ - szNew[k] = subtotal - szCell[i] - 2; - cntNew[k] = i; - if( leafData ){ i--; } - subtotal = 0; - k++; - if( k>NB+1 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } - } - } - szNew[k] = subtotal; - cntNew[k] = nCell; - k++; + for(i=0; inFree; + if( szNew[i]<0 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } + for(j=0; jnOverflow; j++){ + szNew[i] += 2 + p->xCellSize(p, p->apOvfl[j]); + } + cntNew[i] = cntOld[i]; + } + k = nOld; + for(i=0; iusableSpace ){ + 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]usableSpace ) break; + szNew[i] += sz; + cntNew[i]++; + if( !leafData ){ + sz = cntNew[i]=nCell ){ + k = i+1; + }else if( cntNew[i] - (i>0 ? cntNew[i-1] : 0) <= 0 ){ + rc = SQLITE_CORRUPT_BKPT; + goto balance_cleanup; + } + } /* ** The packing computed by the previous block is biased toward the siblings @@ -7124,6 +7156,10 @@ static int balance_nonroot( szRight += szCell[d] + 2; szLeft -= szCell[r] + 2; cntNew[i-1]--; + if( cntNew[i-1] <= 0 ){ + rc = SQLITE_CORRUPT_BKPT; + goto balance_cleanup; + } r = cntNew[i-1] - 1; d = r + 1 - leafData; } @@ -7294,9 +7330,11 @@ static int balance_nonroot( ){ if( !leafCorrection ){ ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc); + if( rc ) goto balance_cleanup; } if( szCell[i]>pNew->minLocal ){ ptrmapPutOvflPtr(pNew, pCell, &rc); + if( rc ) goto balance_cleanup; } } } @@ -7404,7 +7442,8 @@ static int balance_nonroot( 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]++; apNew[iPg]->nFree = usableSpace-szNew[iPg]; assert( apNew[iPg]->nOverflow==0 );