From: drh Date: Tue, 23 Sep 2014 22:36:25 +0000 (+0000) Subject: Avoid calling btreeParseCellPtr() from within fillInCell() since most of X-Git-Tag: version-3.8.7~78 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6200c88123e5933dc81ec132d0c03f8bff86a07b;p=thirdparty%2Fsqlite.git Avoid calling btreeParseCellPtr() from within fillInCell() since most of what btreeParseCellPtr() computes is ignored by fillInCell(). Instead, have fillInCell() compute the values it needs inline. Performance improvement. FossilOrigin-Name: 4147f6671e3faa8ddffab8387a6c7d9b5b962fc8 --- diff --git a/manifest b/manifest index 70db7cda92..2923bfbe6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\sCellInfo\sstructure\sfor\sa\ssize\sreduction\sand\sperformance\nimprovement. -D 2014-09-23T21:25:19.710 +C Avoid\scalling\sbtreeParseCellPtr()\sfrom\swithin\sfillInCell()\ssince\smost\sof\nwhat\sbtreeParseCellPtr()\scomputes\sis\signored\sby\sfillInCell().\s\sInstead,\shave\nfillInCell()\scompute\sthe\svalues\sit\sneeds\sinline.\s\sPerformance\simprovement. +D 2014-09-23T22:36:25.858 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -172,7 +172,7 @@ F src/auth.c d8abcde53426275dab6243b441256fcd8ccbebb2 F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5 -F src/btree.c 2a7c67d474624732612f97a89e34cf85f8cd4905 +F src/btree.c 11cf36074a9829bad4506e8486bfd2431168bb54 F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8 F src/btreeInt.h a5a869ec2c3e56ee9e214ee748d7942716be0340 F src/build.c 8dbca25988045fbf2a33c9631c42706fa6449e60 @@ -1200,7 +1200,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 d2962a5f388f30a02429e0c8b87399f482b5604c -R 3633e95932853227476c5d6e8f02e193 +P bf59df66b3613c38cfb13a68091b8328ebb22c78 +R 7c25e7d21782a499afecd58eb6881944 U drh -Z 6131f39965fefa27be7e69636d8311d7 +Z 9128d4e264c0fc76a3ba82d24c937cbe diff --git a/manifest.uuid b/manifest.uuid index 24ab1f920d..9320755605 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bf59df66b3613c38cfb13a68091b8328ebb22c78 \ No newline at end of file +4147f6671e3faa8ddffab8387a6c7d9b5b962fc8 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 233f674f0f..5d05e98d85 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5611,7 +5611,6 @@ static int fillInCell( BtShared *pBt = pPage->pBt; Pgno pgnoOvfl = 0; int nHeader; - CellInfo info; assert( sqlite3_mutex_held(pPage->pBt->mutex) ); @@ -5621,24 +5620,18 @@ static int fillInCell( || sqlite3PagerIswriteable(pPage->pDbPage) ); /* Fill in the header. */ - nHeader = 0; - if( !pPage->leaf ){ - nHeader += 4; - } + nHeader = pPage->childPtrSize; + nPayload = nData + nZero; if( pPage->hasData ){ - nHeader += putVarint32(&pCell[nHeader], nData+nZero); + assert( pPage->intKey ); + nHeader += putVarint32(&pCell[nHeader], nPayload); }else{ - nData = nZero = 0; + assert( nData==0 ); + assert( nZero==0 ); } nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey); - btreeParseCellPtr(pPage, pCell, &info); - assert( nHeader=(int)(info.pPayload - pCell) ); - assert( info.nKey==nKey ); - assert( pPage->intKey==0 || info.nPayload==(u32)(nData+nZero) ); - assert( pPage->intKey==1 || info.nPayload==nKey ); - /* Fill in the payload */ - nPayload = nData + nZero; + /* Fill in the payload size */ if( pPage->intKey ){ pSrc = pData; nSrc = nData; @@ -5647,15 +5640,55 @@ static int fillInCell( if( NEVER(nKey>0x7fffffff || pKey==0) ){ return SQLITE_CORRUPT_BKPT; } - nPayload += (int)nKey; + nPayload = (int)nKey; pSrc = pKey; nSrc = (int)nKey; } - *pnSize = info.nSize; - spaceLeft = info.nLocal; + if( nPayload<=pPage->maxLocal ){ + n = nHeader + nPayload; + testcase( n==3 ); + testcase( n==4 ); + if( n<4 ) n = 4; + *pnSize = n; + spaceLeft = nPayload; + pPrior = pCell; + }else{ + int mn = pPage->minLocal; + n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4); + testcase( n==pPage->maxLocal ); + testcase( n==pPage->maxLocal+1 ); + if( n > pPage->maxLocal ) n = mn; + spaceLeft = n; + *pnSize = n + nHeader + 4; + pPrior = &pCell[nHeader+n]; + } pPayload = &pCell[nHeader]; - pPrior = &pCell[info.iOverflow]; + /* At this point variables should be set as follows: + ** + ** nPayload Total payload size in bytes + ** pPayload Begin writing payload here + ** spaceLeft Space available at pPayload. If nPayload>spaceLeft, + ** that means content must spill into overflow pages. + ** *pnSize Size of the local cell (not counting overflow pages) + ** pPrior Where to write the pgno of the first overflow page + ** + ** Use a call to btreeParseCellPtr() to verify that the values above + ** were computed correctly. + */ +#if SQLITE_DEBUG + { + CellInfo info; + btreeParseCellPtr(pPage, pCell, &info); + assert( nHeader=(int)(info.pPayload - pCell) ); + assert( info.nKey==nKey ); + assert( *pnSize == info.nSize ); + assert( spaceLeft == info.nLocal ); + assert( pPrior == &pCell[info.iOverflow] ); + } +#endif + + /* Write the payload into the local Cell and any extra into overflow pages */ while( nPayload>0 ){ if( spaceLeft==0 ){ #ifndef SQLITE_OMIT_AUTOVACUUM