From: drh Date: Sat, 20 Jun 2015 18:13:59 +0000 (+0000) Subject: Split out all four cases of cellSizePtr() into different methods, each optimized X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2Fbtree-opt;p=thirdparty%2Fsqlite.git Split out all four cases of cellSizePtr() into different methods, each optimized for the specific page type. This gives a 0.36% performance increase at a cost of about 300 bytes of code. FossilOrigin-Name: 522502ec18bffbb8e1516de542be270a9302df1c --- diff --git a/manifest b/manifest index 9332d172a2..d7c0bd82f1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sfuzztest\sdata\susing\sthe\slatest\stest\svectors\sdiscovered\sby\sAFL. -D 2015-06-20T14:11:56.166 +C Split\sout\sall\sfour\scases\sof\scellSizePtr()\sinto\sdifferent\smethods,\seach\soptimized\nfor\sthe\sspecific\spage\stype.\s\sThis\sgives\sa\s0.36%\sperformance\sincrease\sat\sa\scost\nof\sabout\s300\sbytes\sof\scode. +D 2015-06-20T18:13:59.692 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 173c2ba1b8cf941971683f584965369791125f12 +F src/btree.c a311c31f1d8da477c37ae7217ea6624312b2148d F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 F src/btreeInt.h 6ece2dd9c8e2eac05f0a8ded8772a44e96486c65 F src/build.c b3f15255d5b16e42dafeaa638fd4f8a47c94ed70 @@ -1286,7 +1286,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7cdbae625eb029538a693d2bebec465a6f65fb90 -R 5add07a39efb3611e2cfa0ac20a2c5f5 +P b97f9cf73e503c7285ba3a801e1f932f222d96b2 +R abd877b06a45970f5668a06bcf76a6b3 +T *branch * btree-opt +T *sym-btree-opt * +T -sym-trunk * U drh -Z 71db4d574368380e4b14cadc01f6d8d0 +Z 3e76e6635cfc3906ab35c190cf944ecd diff --git a/manifest.uuid b/manifest.uuid index ad06e9f3b1..c142dbe4f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b97f9cf73e503c7285ba3a801e1f932f222d96b2 \ No newline at end of file +522502ec18bffbb8e1516de542be270a9302df1c \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index e64139b800..c3a7be3d7d 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1175,10 +1175,12 @@ static void btreeParseCell( ** the space used by the cell pointer. ** ** cellSizePtrNoPayload() => table internal nodes -** cellSizePtr() => all index nodes & table leaf nodes +** cellSizeTableLeaf() => table leaf nodes +** cellSizeIndexInternal() => internal index nodes +** cellSizeIndexLeaf() => leaf index nodes */ -static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ - u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */ +static u16 cellSizeTableLeaf(MemPage *pPage, u8 *pCell){ + u8 *pIter = pCell; /* For looping over bytes of pCell */ u8 *pEnd; /* End mark for a varint */ u32 nSize; /* Size value to return */ @@ -1192,6 +1194,7 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ #endif assert( pPage->noPayload==0 ); + assert( pPage->childPtrSize==0 ); nSize = *pIter; if( nSize>=0x80 ){ pEnd = &pIter[8]; @@ -1201,13 +1204,56 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ }while( *(pIter)>=0x80 && pIterintKey ){ - /* pIter now points at the 64-bit integer key value, a variable length - ** integer. The following block moves pIter to point at the first byte - ** past the end of the key value. */ - pEnd = &pIter[9]; - while( (*pIter++)&0x80 && pIterintKey ); + /* pIter now points at the 64-bit integer key value, a variable length + ** integer. The following block moves pIter to point at the first byte + ** past the end of the key value. */ + pEnd = &pIter[9]; + while( (*pIter++)&0x80 && pItermaxLocal ); + testcase( nSize==pPage->maxLocal+1 ); + if( nSize<=pPage->maxLocal ){ + nSize += (u32)(pIter - pCell); + if( nSize<4 ) nSize = 4; + }else{ + int minLocal = pPage->minLocal; + nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); + testcase( nSize==pPage->maxLocal ); + testcase( nSize==pPage->maxLocal+1 ); + if( nSize>pPage->maxLocal ){ + nSize = minLocal; + } + nSize += 4 + (u16)(pIter - pCell); } + assert( nSize==debuginfo.nSize || CORRUPT_DB ); + return (u16)nSize; +} +static u16 cellSizeIndexLeaf(MemPage *pPage, u8 *pCell){ + u8 *pIter = pCell; /* For looping over bytes of pCell */ + u8 *pEnd; /* End mark for a varint */ + u32 nSize; /* Size value to return */ + +#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; + pPage->xParseCell(pPage, pCell, &debuginfo); +#endif + + assert( pPage->noPayload==0 ); + assert( pPage->childPtrSize==0 ); + nSize = *pIter; + if( nSize>=0x80 ){ + pEnd = &pIter[8]; + nSize &= 0x7f; + do{ + nSize = (nSize<<7) | (*++pIter & 0x7f); + }while( *(pIter)>=0x80 && pIterintKey==0 ); testcase( nSize==pPage->maxLocal ); testcase( nSize==pPage->maxLocal+1 ); if( nSize<=pPage->maxLocal ){ @@ -1226,6 +1272,50 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ assert( nSize==debuginfo.nSize || CORRUPT_DB ); return (u16)nSize; } +static u16 cellSizePtrIndexInternal(MemPage *pPage, u8 *pCell){ + u8 *pIter = pCell + 4; /* For looping over bytes of pCell */ + u8 *pEnd; /* End mark for a varint */ + u32 nSize; /* Size value to return */ + +#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; + pPage->xParseCell(pPage, pCell, &debuginfo); +#endif + + assert( pPage->childPtrSize==4 ); + assert( pPage->noPayload==0 ); + nSize = *pIter; + if( nSize>=0x80 ){ + pEnd = &pIter[8]; + nSize &= 0x7f; + do{ + nSize = (nSize<<7) | (*++pIter & 0x7f); + }while( *(pIter)>=0x80 && pIterintKey==0 ); + testcase( nSize==pPage->maxLocal ); + testcase( nSize==pPage->maxLocal+1 ); + if( nSize<=pPage->maxLocal ){ + nSize += (u32)(pIter - pCell); + assert( nSize>=4 ); + }else{ + int minLocal = pPage->minLocal; + nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); + testcase( nSize==pPage->maxLocal ); + testcase( nSize==pPage->maxLocal+1 ); + if( nSize>pPage->maxLocal ){ + nSize = minLocal; + } + nSize += 4 + (u16)(pIter - 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 */ @@ -1633,7 +1723,6 @@ 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 @@ -1646,6 +1735,7 @@ static int decodeFlags(MemPage *pPage, int flagByte){ if( pPage->leaf ){ pPage->intKeyLeaf = 1; pPage->noPayload = 0; + pPage->xCellSize = cellSizeTableLeaf; pPage->xParseCell = btreeParseCellPtr; }else{ pPage->intKeyLeaf = 0; @@ -1668,6 +1758,11 @@ static int decodeFlags(MemPage *pPage, int flagByte){ pPage->xParseCell = btreeParseCellPtrIndex; pPage->maxLocal = pBt->maxLocal; pPage->minLocal = pBt->minLocal; + if( pPage->leaf ){ + pPage->xCellSize = cellSizeIndexLeaf; + }else{ + pPage->xCellSize = cellSizePtrIndexInternal; + } }else{ /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is ** an error. */