More simplifications and performance improvements to cell allocation

logic associated with allocateSpace().

FossilOrigin-Name: 78da0f69cb3289e332018864004f319f2764a5c8
This commit is contained in:
drh 2015-06-25 18:36:13 +00:00
parent e674bf1648
commit b7580e84a8
3 changed files with 26 additions and 28 deletions

View File

@ -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

View File

@ -1 +1 @@
d67b0ed1054cbb7ea2cdd74720d4d6e0227cec14
78da0f69cb3289e332018864004f319f2764a5c8

View File

@ -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<iEnd; i++){
int sz, rc;
u8 *pSlot;
sz = cachedCellSize(pCArray, i);
if( bFreelist==0 || (pSlot = pageFindSlot(pPg, sz, &rc, 0))==0 ){
if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){
pData -= sz;
if( pData<pBegin ) return 1;
pSlot = pData;