From: drh Date: Fri, 19 Jun 2015 15:07:14 +0000 (+0000) Subject: Make cellSizePtr() a method on the MemPage object, with alternative X-Git-Tag: version-3.8.11~149 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=25ada07ab405348bdb7398afcd71e72d59a1043c;p=thirdparty%2Fsqlite.git Make cellSizePtr() a method on the MemPage object, with alternative implementations depending on the page type. This results is a small performance improvement and size reduction. FossilOrigin-Name: 02f7e9d7d7b93d0b6bbd6cc0d0359b3b741b9931 --- diff --git a/manifest b/manifest index 806cfda95a..64a9e9fb2d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\s#ifdef\schanges\sin\sspeedtest1.c\sin\sorder\sto\ssupport\sSQLite\sback\sto\nversion\s3.3.9\sand\sperhaps\seven\searlier. -D 2015-06-18T15:26:09.205 +C Make\scellSizePtr()\sa\smethod\son\sthe\sMemPage\sobject,\swith\salternative\nimplementations\sdepending\son\sthe\spage\stype.\s\sThis\sresults\sis\sa\ssmall\sperformance\nimprovement\sand\ssize\sreduction. +D 2015-06-19T15:07:14.566 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1063c58075b7400d93326b0eb332b48a54f53025 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -192,9 +192,9 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3 F src/bitvec.c 5eb7958c3bf65210211cbcfc44eff86d0ded7c9d F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 -F src/btree.c 02caf39192ed1f5c7157a1aac0b2ff23389233de +F src/btree.c 960e66f4a9fd494c5712f4342432a2fb1cbb72c1 F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 -F src/btreeInt.h 973a22a6fd61350b454ad614832b1f0a5e25a1e4 +F src/btreeInt.h 97901d5434a22344cd5ae47e80ed677bd21d572d F src/build.c b3f15255d5b16e42dafeaa638fd4f8a47c94ed70 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575 @@ -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 ed96e14adce4a4f94cc6838c46bc97937c4cb72a -R 4e77e4d1b1f5f9af9315f930f1585b67 +P 9246eca54adaee571dab0c066afaa604fcf9c44f +R 65525ba5a493bb8d3d370265d6f2abe8 U drh -Z 4a2d5290228b5807450e51ccee479c2e +Z b80278f806bcab0592c2162609b43f46 diff --git a/manifest.uuid b/manifest.uuid index e752e4c060..69d741e4be 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9246eca54adaee571dab0c066afaa604fcf9c44f \ No newline at end of file +02f7e9d7d7b93d0b6bbd6cc0d0359b3b741b9931 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index eab5b98426..9260b3a910 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1065,6 +1065,11 @@ static void btreeParseCell( ** data area of the btree-page. The return number includes the cell ** data header and the local payload, but not any overflow page or ** the space used by the cell pointer. +** +** The first implementation, cellSizePtr(), handles pages that contain +** payload, which is to say all index pages and left table pages. The +** second cellSizePtrNoPayload() implemention is a high-speed version +** for pages that contain no payload - internal table pages. */ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */ @@ -1080,12 +1085,7 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ btreeParseCellPtr(pPage, pCell, &debuginfo); #endif - if( pPage->noPayload ){ - pEnd = &pIter[9]; - while( (*pIter++)&0x80 && pIterchildPtrSize==4 ); - return (u16)(pIter - pCell); - } + assert( pPage->noPayload==0 ); nSize = *pIter; if( nSize>=0x80 ){ pEnd = &pIter[9]; @@ -1120,12 +1120,32 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ assert( nSize==debuginfo.nSize || CORRUPT_DB ); return (u16)nSize; } +static u16 cellSizePtrNoPayload(MemPage *pPage, u8 *pCell){ + u8 *pIter = pCell + 4; /* For looping over bytes of pCell */ + u8 *pEnd; /* End mark for a varint */ + +#ifdef SQLITE_DEBUG + /* The value returned by this function should always be the same as + ** the (CellInfo.nSize) value found by doing a full parse of the + ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of + ** this function verifies that this invariant is not violated. */ + CellInfo debuginfo; + btreeParseCellPtr(pPage, pCell, &debuginfo); +#endif + + assert( pPage->childPtrSize==4 ); + pEnd = pIter + 9; + while( (*pIter++)&0x80 && pIterxCellSize(pPage, findCell(pPage, iCell)); } #endif @@ -1203,7 +1223,7 @@ static int defragmentPage(MemPage *pPage){ return SQLITE_CORRUPT_BKPT; } assert( pc>=iCellFirst && pc<=iCellLast ); - size = cellSizePtr(pPage, &src[pc]); + size = pPage->xCellSize(pPage, &src[pc]); cbrk -= size; if( cbrkusableSize ){ return SQLITE_CORRUPT_BKPT; @@ -1507,6 +1527,7 @@ static int decodeFlags(MemPage *pPage, int flagByte){ pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 ); flagByte &= ~PTF_LEAF; pPage->childPtrSize = 4-4*pPage->leaf; + pPage->xCellSize = cellSizePtr; pBt = pPage->pBt; if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){ /* EVIDENCE-OF: R-03640-13415 A value of 5 means the page is an interior @@ -1516,8 +1537,14 @@ static int decodeFlags(MemPage *pPage, int flagByte){ ** table b-tree page. */ assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 ); pPage->intKey = 1; - pPage->intKeyLeaf = pPage->leaf; - pPage->noPayload = !pPage->leaf; + if( pPage->leaf ){ + pPage->intKeyLeaf = 1; + pPage->noPayload = 0; + }else{ + pPage->intKeyLeaf = 0; + pPage->noPayload = 1; + pPage->xCellSize = cellSizePtrNoPayload; + } pPage->maxLocal = pBt->maxLeaf; pPage->minLocal = pBt->minLeaf; }else if( flagByte==PTF_ZERODATA ){ @@ -1624,7 +1651,7 @@ static int btreeInitPage(MemPage *pPage){ if( pciCellLast ){ return SQLITE_CORRUPT_BKPT; } - sz = cellSizePtr(pPage, &data[pc]); + sz = pPage->xCellSize(pPage, &data[pc]); testcase( pc+sz==usableSize ); if( pc+sz>usableSize ){ return SQLITE_CORRUPT_BKPT; @@ -6096,7 +6123,7 @@ static void insertCell( ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size ** might be less than 8 (leaf-size + pointer) on the interior node. Hence ** the term after the || in the following assert(). */ - assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) ); + assert( sz==pPage->xCellSize(pPage, pCell) || (sz==8 && iChild>0) ); if( pPage->nOverflow || sz+2>pPage->nFree ){ if( pTemp ){ memcpy(pTemp, pCell, sz); @@ -6187,8 +6214,8 @@ static void rebuildPage( memcpy(pData, pCell, szCell[i]); put2byte(pCellptr, (pData - aData)); pCellptr += 2; - assert( szCell[i]==cellSizePtr(pPg, pCell) || CORRUPT_DB ); - testcase( szCell[i]==cellSizePtr(pPg,pCell) ); + assert( szCell[i]==pPg->xCellSize(pPg, pCell) || CORRUPT_DB ); + testcase( szCell[i]==pPg->xCellSize(pPg,pCell) ); } /* The pPg->nFree field is now set incorrectly. The caller will fix it. */ @@ -6478,7 +6505,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ u8 *pOut = &pSpace[4]; u8 *pCell = pPage->apOvfl[0]; - u16 szCell = cellSizePtr(pPage, pCell); + u16 szCell = pPage->xCellSize(pPage, pCell); u8 *pStop; assert( sqlite3PagerIswriteable(pNew->pDbPage) ); @@ -6784,12 +6811,12 @@ static int balance_nonroot( if( i+nxDiv==pParent->aiOvfl[0] && pParent->nOverflow ){ apDiv[i] = pParent->apOvfl[0]; pgno = get4byte(apDiv[i]); - szNew[i] = cellSizePtr(pParent, apDiv[i]); + szNew[i] = pParent->xCellSize(pParent, apDiv[i]); pParent->nOverflow = 0; }else{ apDiv[i] = findCell(pParent, i+nxDiv-pParent->nOverflow); pgno = get4byte(apDiv[i]); - szNew[i] = cellSizePtr(pParent, apDiv[i]); + szNew[i] = pParent->xCellSize(pParent, apDiv[i]); /* Drop the cell from the parent page. apDiv[i] still points to ** the cell within the parent, even though it has been dropped. @@ -6879,7 +6906,7 @@ static int balance_nonroot( for(j=0; jxCellSize(pOld, apCell[nCell]); nCell++; } }else{ @@ -6889,7 +6916,7 @@ static int balance_nonroot( for(j=0; jxCellSize(pOld, apCell[nCell]); nCell++; } } @@ -7207,7 +7234,7 @@ static int balance_nonroot( */ if( szCell[j]==4 ){ assert(leafCorrection==4); - sz = cellSizePtr(pParent, pCell); + sz = pParent->xCellSize(pParent, pCell); } } iOvflSpace += sz; @@ -7652,7 +7679,7 @@ int sqlite3BtreeInsert( assert( newCell!=0 ); rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew); if( rc ) goto end_insert; - assert( szNew==cellSizePtr(pPage, newCell) ); + assert( szNew==pPage->xCellSize(pPage, newCell) ); assert( szNew <= MX_CELL_SIZE(pBt) ); idx = pCur->aiIdx[pCur->iPage]; if( loc==0 ){ @@ -7794,7 +7821,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){ pCell = findCell(pLeaf, pLeaf->nCell-1); if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT; - nCell = cellSizePtr(pLeaf, pCell); + nCell = pLeaf->xCellSize(pLeaf, pCell); assert( MX_CELL_SIZE(pBt) >= nCell ); pTmp = pBt->pTmpSpace; assert( pTmp!=0 ); @@ -8806,7 +8833,7 @@ static int checkTreePage( int pc = get2byte(&data[cellStart+i*2]); u32 size = 65536; if( pc<=usableSize-4 ){ - size = cellSizePtr(pPage, &data[pc]); + size = pPage->xCellSize(pPage, &data[pc]); } if( (int)(pc+size-1)>=usableSize ){ pCheck->zPfx = 0; diff --git a/src/btreeInt.h b/src/btreeInt.h index 33ef641059..6c03a98644 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -295,6 +295,7 @@ struct MemPage { u8 *aDataEnd; /* One byte past the end of usable data */ u8 *aCellIdx; /* The cell index area */ DbPage *pDbPage; /* Pager page handle */ + u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */ Pgno pgno; /* Page number for this page */ };