From: drh Date: Wed, 20 Aug 2014 18:43:44 +0000 (+0000) Subject: A small performance improvement in freeSpace() by special-casing the X-Git-Tag: version-3.8.7~180 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7bc4c454dab1568702db8ef230c624edc35ed815;p=thirdparty%2Fsqlite.git A small performance improvement in freeSpace() by special-casing the relatively common case of an empty freelist. FossilOrigin-Name: 49f44d355ff70744e4951baca2481c7c2b6c02b3 --- diff --git a/manifest b/manifest index 4fe8e5ec20..0e55755198 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reimplement\sthe\sfreeSpace()\sroutine\sin\sbtree.c\sso\sthat\sit\sruns\sfaster. -D 2014-08-20T17:56:27.585 +C A\ssmall\sperformance\simprovement\sin\sfreeSpace()\sby\sspecial-casing\sthe\nrelatively\scommon\scase\sof\san\sempty\sfreelist. +D 2014-08-20T18:43:44.510 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -167,7 +167,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c fe2d11c8c0d99e324614141ad012b37d0601cf59 +F src/btree.c 4195fed5741b4dbcc9831b623aec487258f3e62d F src/btree.h 4245a349bfe09611d7ff887dbc3a80cee8b7955a F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3 F src/build.c 5abf794fe8a605f2005b422e98a3cedad9b9ef5b @@ -1186,7 +1186,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7e63089a191f29aefde05e89bb612f3036cfa034 -R cbff1ae81d05ca3b78b420deaaa6083f +P fe4fd014b42b7b158ca968f1535b5636c67769f6 +R 865eceb09aea170bb70d44b771b85e6e U drh -Z d684bbbc1bfe7cdee532398c2232ddf8 +Z 0631afdcc5729e41fc50a75336710200 diff --git a/manifest.uuid b/manifest.uuid index 238682a66d..2bb2527d30 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fe4fd014b42b7b158ca968f1535b5636c67769f6 \ No newline at end of file +49f44d355ff70744e4951baca2481c7c2b6c02b3 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index c10e2f1c32..56718b69d6 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1330,47 +1330,51 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ */ hdr = pPage->hdrOffset; iPtr = hdr + 1; - while( (iFreeBlk = get2byte(&data[iPtr]))>0 && iFreeBlkiLast ) return SQLITE_CORRUPT_BKPT; - assert( iFreeBlk>iPtr || iFreeBlk==0 ); - - /* At this point: - ** iFreeBlk: First freeblock after iStart, or zero if none - ** iPtr: The address of a pointer iFreeBlk - ** - ** Check to see if iFreeBlk should be coalesced onto the end of iStart. - */ - if( iFreeBlk && iEnd+3>=iFreeBlk ){ - nFrag = iFreeBlk - iEnd; - if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_BKPT; - iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]); - iSize = iEnd - iStart; - iFreeBlk = get2byte(&data[iFreeBlk]); - } - - /* If iPtr is another freeblock (that is, if iPtr is not the freelist pointer - ** in the page header) then check to see if iStart should be coalesced - ** onto the end of iPtr. - */ - if( iPtr>hdr+1 ){ - int iPtrEnd = iPtr + get2byte(&data[iPtr+2]); - if( iPtrEnd+3>=iStart ){ - if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT; - nFrag += iStart - iPtrEnd; - iSize = iEnd - iPtr; - iStart = iPtr; + if( data[iPtr+1]==0 && data[iPtr]==0 ){ + iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */ + }else{ + while( (iFreeBlk = get2byte(&data[iPtr]))>0 && iFreeBlkiLast ) return SQLITE_CORRUPT_BKPT; + assert( iFreeBlk>iPtr || iFreeBlk==0 ); + + /* At this point: + ** iFreeBlk: First freeblock after iStart, or zero if none + ** iPtr: The address of a pointer iFreeBlk + ** + ** Check to see if iFreeBlk should be coalesced onto the end of iStart. + */ + if( iFreeBlk && iEnd+3>=iFreeBlk ){ + nFrag = iFreeBlk - iEnd; + if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_BKPT; + iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]); + iSize = iEnd - iStart; + iFreeBlk = get2byte(&data[iFreeBlk]); + } + + /* If iPtr is another freeblock (that is, if iPtr is not the freelist pointer + ** in the page header) then check to see if iStart should be coalesced + ** onto the end of iPtr. + */ + if( iPtr>hdr+1 ){ + int iPtrEnd = iPtr + get2byte(&data[iPtr+2]); + if( iPtrEnd+3>=iStart ){ + if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT; + nFrag += iStart - iPtrEnd; + iSize = iEnd - iPtr; + iStart = iPtr; + } + } + if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_BKPT; + data[hdr+7] -= nFrag; } - if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_BKPT; - - data[hdr+7] -= nFrag; - if( iPtr==hdr+1 && iStart==get2byte(&data[hdr+5]) ){ + if( iStart==get2byte(&data[hdr+5]) ){ /* The new freeblock is at the beginning of the cell content area, ** so just extend the cell content area rather than create another ** freelist entry */ + if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_BKPT; put2byte(&data[hdr+1], iFreeBlk); put2byte(&data[hdr+5], iEnd); }else{