From: drh Date: Thu, 25 Jun 2015 18:36:13 +0000 (+0000) Subject: More simplifications and performance improvements to cell allocation X-Git-Tag: version-3.8.11~122 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b7580e84a84fb5a0424979e3c99834d666b4a3c5;p=thirdparty%2Fsqlite.git More simplifications and performance improvements to cell allocation logic associated with allocateSpace(). FossilOrigin-Name: 78da0f69cb3289e332018864004f319f2764a5c8 --- diff --git a/manifest b/manifest index fbf418370d..848f3d66c6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reorder\sthe\sterms\sof\sa\sconditional\sfor\sa\ssmall\sperformance\sgain. -D 2015-06-25T16:01:44.112 +C More\ssimplifications\sand\sperformance\simprovements\sto\scell\sallocation\nlogic\sassociated\swith\sallocateSpace(). +D 2015-06-25T18:36:13.826 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 85679f63ebc2c67593479cf22f88539f71f2af70 +F src/btree.c 960a641306010ed25690af8e05d599fe4b9a005d F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 F src/btreeInt.h fdd1aff02fb2a63812bd95716e7f579fc3759107 F src/build.c b3f15255d5b16e42dafeaa638fd4f8a47c94ed70 @@ -1286,7 +1286,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f824e66b0dc120bed227c7446e2663fcad7cc4f6 -R 8aa067d659e72dd17b19d63682b0eebd +P d67b0ed1054cbb7ea2cdd74720d4d6e0227cec14 +R 4a51cc2794802bb6f018a7f1798d3a79 U drh -Z c674ba4fda0e43aa32d59f882342a9d7 +Z 2ec930a14eaee4b6a3bd2ab311de6bca diff --git a/manifest.uuid b/manifest.uuid index 67e0ce0f60..6e77614794 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d67b0ed1054cbb7ea2cdd74720d4d6e0227cec14 \ No newline at end of file +78da0f69cb3289e332018864004f319f2764a5c8 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 646367c2e0..9dbdab9b74 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1351,18 +1351,20 @@ static int defragmentPage(MemPage *pPage){ ** This function may detect corruption within pPg. If corruption is ** detected then *pRc is set to SQLITE_CORRUPT and NULL is returned. ** -** If a slot of at least nByte bytes is found but cannot be used because -** there are already at least 60 fragmented bytes on the page, return NULL. -** In this case, if pbDefrag parameter is not NULL, set *pbDefrag to true. +** Slots on the free list that are between 1 and 3 bytes larger than nByte +** will be ignored if adding the extra space to the fragmentation count +** causes the fragmentation count to exceed 60. */ -static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc, int *pbDefrag){ +static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ const int hdr = pPg->hdrOffset; u8 * const aData = pPg->aData; - int iAddr; - int pc; + int iAddr = hdr + 1; + int pc = get2byte(&aData[iAddr]); + int x; int usableSize = pPg->pBt->usableSize; - for(iAddr=hdr+1; (pc = get2byte(&aData[iAddr]))>0; iAddr=pc){ + assert( pc>0 ); + do{ int size; /* Size of the free slot */ /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of ** increasing offset. */ @@ -1374,8 +1376,7 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc, int *pbDefrag){ ** freeblock form a big-endian integer which is the size of the freeblock ** in bytes, including the 4-byte header. */ size = get2byte(&aData[pc+2]); - if( size>=nByte ){ - int x = size - nByte; + if( (x = size - nByte)>=0 ){ testcase( x==4 ); testcase( x==3 ); if( pc < pPg->cellOffset+2*pPg->nCell || size+pc > usableSize ){ @@ -1384,10 +1385,8 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc, int *pbDefrag){ }else if( x<4 ){ /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total ** number of bytes in fragments may not exceed 60. */ - if( aData[hdr+7]>=60 ){ - if( pbDefrag ) *pbDefrag = 1; - return 0; - } + if( aData[hdr+7]>57 ) return 0; + /* Remove the slot from the free-list. Update the number of ** fragmented bytes within the page. */ memcpy(&aData[iAddr], &aData[pc], 2); @@ -1399,7 +1398,9 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc, int *pbDefrag){ } return &aData[pc + x]; } - } + iAddr = pc; + pc = get2byte(&aData[pc]); + }while( pc ); return 0; } @@ -1458,14 +1459,13 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ testcase( gap+1==top ); testcase( gap==top ); if( (data[hdr+2] || data[hdr+1]) && gap+2<=top ){ - int bDefrag = 0; - u8 *pSpace = pageFindSlot(pPage, nByte, &rc, &bDefrag); - if( rc ) return rc; - if( bDefrag ) goto defragment_page; + u8 *pSpace = pageFindSlot(pPage, nByte, &rc); if( pSpace ){ assert( pSpace>=data && (pSpace - data)<65536 ); *pIdx = (int)(pSpace - data); return SQLITE_OK; + }else if( rc ){ + return rc; } } @@ -1474,7 +1474,6 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ */ testcase( gap+2+nByte==top ); if( gap+2+nByte>top ){ - defragment_page: assert( pPage->nCell>0 || CORRUPT_DB ); rc = defragmentPage(pPage); if( rc ) return rc; @@ -6414,14 +6413,13 @@ static int pageInsertArray( int i; u8 *aData = pPg->aData; u8 *pData = *ppData; - const int bFreelist = aData[1] || aData[2]; int iEnd = iFirst + nCell; assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ for(i=iFirst; i