1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Smaller and faster implementation of the fillInCell() routine.

FossilOrigin-Name: 77074990edef6c42bdfe7ccce1affc8ed64a86dde3ad4fa50b60ba0a6d851eea
This commit is contained in:
drh
2017-08-23 14:45:59 +00:00
parent 489a224bea
commit 5e27e1dc49
3 changed files with 63 additions and 50 deletions

View File

@@ -1,5 +1,5 @@
C Update\sdocumentation\sto\smake\sit\sclear\sthat\sSQLITE_SOURCE_ID\sand\nsqlite3_sourceid()\smight\schanges\sif\sthe\ssource\scode\sis\sedited. C Smaller\sand\sfaster\simplementation\sof\sthe\sfillInCell()\sroutine.
D 2017-08-22T21:23:02.258 D 2017-08-23T14:45:59.667
F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136
@@ -399,7 +399,7 @@ F src/auth.c 6277d63837357549fe14e723490d6dc1a38768d71c795c5eb5c0f8a99f918f73
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
F src/btree.c e1a98bef27d6189df5c5b8b3c9b5e53d6b74bf9a936af97757c21e9ea6a5c6b2 F src/btree.c ea10ca63430533c358da32e5d2b8b22aa3c6a9e84f295139e4e5bb00f635726d
F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09 F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09
F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc
F src/build.c b47a0320c6d237718b8f493ac97d37d1071bce12aca668b15219187150c41295 F src/build.c b47a0320c6d237718b8f493ac97d37d1071bce12aca668b15219187150c41295
@@ -1650,7 +1650,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 564c7340a3368501c3da885afde52123ed7f558801f6190cbe6173dfe9704b70 P e69c0c8770d3cc2fcdc779c6290caf1575644d457326caa00327b9070251d620
R b1a5f4a03931a03b3cf49a93760947b3 R 66591a7ad128e50f7a0c04de7cb52832
U drh U drh
Z 80eecc829d5290754bef086590571027 Z 50b9a412665b926c36fcdf17b0a625f8

View File

@@ -1 +1 @@
e69c0c8770d3cc2fcdc779c6290caf1575644d457326caa00327b9070251d620 77074990edef6c42bdfe7ccce1affc8ed64a86dde3ad4fa50b60ba0a6d851eea

View File

@@ -6218,21 +6218,20 @@ static int fillInCell(
){ ){
int nPayload; int nPayload;
const u8 *pSrc; const u8 *pSrc;
int nSrc, n, rc; int nSrc, n, rc, mn;
int spaceLeft; int spaceLeft;
MemPage *pOvfl = 0; MemPage *pToRelease;
MemPage *pToRelease = 0;
unsigned char *pPrior; unsigned char *pPrior;
unsigned char *pPayload; unsigned char *pPayload;
BtShared *pBt = pPage->pBt; BtShared *pBt;
Pgno pgnoOvfl = 0; Pgno pgnoOvfl;
int nHeader; int nHeader;
assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( sqlite3_mutex_held(pPage->pBt->mutex) );
/* pPage is not necessarily writeable since pCell might be auxiliary /* pPage is not necessarily writeable since pCell might be auxiliary
** buffer space that is separate from the pPage buffer area */ ** buffer space that is separate from the pPage buffer area */
assert( pCell<pPage->aData || pCell>=&pPage->aData[pBt->pageSize] assert( pCell<pPage->aData || pCell>=&pPage->aData[pPage->pBt->pageSize]
|| sqlite3PagerIswriteable(pPage->pDbPage) ); || sqlite3PagerIswriteable(pPage->pDbPage) );
/* Fill in the header. */ /* Fill in the header. */
@@ -6252,25 +6251,36 @@ static int fillInCell(
} }
/* Fill in the payload */ /* Fill in the payload */
pPayload = &pCell[nHeader];
if( nPayload<=pPage->maxLocal ){ if( nPayload<=pPage->maxLocal ){
/* This is the common case where everything fits on the btree page
** and no overflow pages are required. */
n = nHeader + nPayload; n = nHeader + nPayload;
testcase( n==3 ); testcase( n==3 );
testcase( n==4 ); testcase( n==4 );
if( n<4 ) n = 4; if( n<4 ) n = 4;
*pnSize = n; *pnSize = n;
spaceLeft = nPayload; assert( nSrc<=nPayload );
pPrior = pCell; testcase( nSrc<nPayload );
}else{ memcpy(pPayload, pSrc, nSrc);
int mn = pPage->minLocal; memset(pPayload+nSrc, 0, nPayload-nSrc);
n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4); return SQLITE_OK;
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];
/* If we reach this point, it means that some of the content will need
** to spill onto overflow pages.
*/
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];
pToRelease = 0;
pgnoOvfl = 0;
pBt = pPage->pBt;
/* At this point variables should be set as follows: /* At this point variables should be set as follows:
** **
@@ -6296,8 +6306,35 @@ static int fillInCell(
#endif #endif
/* Write the payload into the local Cell and any extra into overflow pages */ /* Write the payload into the local Cell and any extra into overflow pages */
while( nPayload>0 ){ while( 1 ){
n = nPayload;
if( n>spaceLeft ) n = spaceLeft;
/* If pToRelease is not zero than pPayload points into the data area
** of pToRelease. Make sure pToRelease is still writeable. */
assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) );
/* If pPayload is part of the data area of pPage, then make sure pPage
** is still writeable */
assert( pPayload<pPage->aData || pPayload>=&pPage->aData[pBt->pageSize]
|| sqlite3PagerIswriteable(pPage->pDbPage) );
if( nSrc>=n ){
memcpy(pPayload, pSrc, n);
}else if( nSrc>0 ){
n = nSrc;
memcpy(pPayload, pSrc, n);
}else{
memset(pPayload, 0, n);
}
nPayload -= n;
if( nPayload<=0 ) break;
pPayload += n;
pSrc += n;
nSrc -= n;
spaceLeft -= n;
if( spaceLeft==0 ){ if( spaceLeft==0 ){
MemPage *pOvfl = 0;
#ifndef SQLITE_OMIT_AUTOVACUUM #ifndef SQLITE_OMIT_AUTOVACUUM
Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */ Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
if( pBt->autoVacuum ){ if( pBt->autoVacuum ){
@@ -6350,30 +6387,6 @@ static int fillInCell(
pPayload = &pOvfl->aData[4]; pPayload = &pOvfl->aData[4];
spaceLeft = pBt->usableSize - 4; spaceLeft = pBt->usableSize - 4;
} }
n = nPayload;
if( n>spaceLeft ) n = spaceLeft;
/* If pToRelease is not zero than pPayload points into the data area
** of pToRelease. Make sure pToRelease is still writeable. */
assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) );
/* If pPayload is part of the data area of pPage, then make sure pPage
** is still writeable */
assert( pPayload<pPage->aData || pPayload>=&pPage->aData[pBt->pageSize]
|| sqlite3PagerIswriteable(pPage->pDbPage) );
if( nSrc>0 ){
if( n>nSrc ) n = nSrc;
assert( pSrc );
memcpy(pPayload, pSrc, n);
}else{
memset(pPayload, 0, n);
}
nPayload -= n;
pPayload += n;
pSrc += n;
nSrc -= n;
spaceLeft -= n;
} }
releasePage(pToRelease); releasePage(pToRelease);
return SQLITE_OK; return SQLITE_OK;