Simplify the CellInfo structure for a size reduction and performance

improvement.

FossilOrigin-Name: bf59df66b3613c38cfb13a68091b8328ebb22c78
This commit is contained in:
drh 2014-09-23 21:25:19 +00:00
parent 3b8fea9ec6
commit ab1cc58b70
4 changed files with 38 additions and 48 deletions

View File

@ -1,5 +1,5 @@
C Add\sthe\s"multiplex_truncate"\sPRAGMA\sto\sthe\smultiplexor\sextension,\sfor\nquerying\sand\ssetting\sthe\struncate\sflag\son\sa\sdatabase\sconnection. C Simplify\sthe\sCellInfo\sstructure\sfor\sa\ssize\sreduction\sand\sperformance\nimprovement.
D 2014-09-23T18:30:00.961 D 2014-09-23T21:25:19.710
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -172,9 +172,9 @@ F src/auth.c d8abcde53426275dab6243b441256fcd8ccbebb2
F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5 F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5
F src/btree.c c2645014c525c0b4a8327971c331f55b8747b443 F src/btree.c 2a7c67d474624732612f97a89e34cf85f8cd4905
F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8 F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8
F src/btreeInt.h e0ecb5dba292722039a7540beb3fc448103273cc F src/btreeInt.h a5a869ec2c3e56ee9e214ee748d7942716be0340
F src/build.c 8dbca25988045fbf2a33c9631c42706fa6449e60 F src/build.c 8dbca25988045fbf2a33c9631c42706fa6449e60
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
F src/complete.c 535183afb3c75628b78ce82612931ac7cdf26f14 F src/complete.c 535183afb3c75628b78ce82612931ac7cdf26f14
@ -1200,7 +1200,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P ae9a42b268ad3f7d21a5813bb931e795c6917014 P d2962a5f388f30a02429e0c8b87399f482b5604c
R 38a39c43ba2ffbcd445b1883953d7c57 R 3633e95932853227476c5d6e8f02e193
U drh U drh
Z 9797dd2e522d2cafa5364dec0ef721e8 Z 6131f39965fefa27be7e69636d8311d7

View File

@ -1 +1 @@
d2962a5f388f30a02429e0c8b87399f482b5604c bf59df66b3613c38cfb13a68091b8328ebb22c78

View File

@ -977,38 +977,33 @@ static void btreeParseCellPtr(
u8 *pCell, /* Pointer to the cell text. */ u8 *pCell, /* Pointer to the cell text. */
CellInfo *pInfo /* Fill in this structure */ CellInfo *pInfo /* Fill in this structure */
){ ){
u16 n; /* Number bytes in cell content header */ u8 *pIter = &pCell[pPage->childPtrSize];
u32 nPayload; /* Number of bytes of cell payload */ u32 nPayload; /* Number of bytes of cell payload */
assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( sqlite3_mutex_held(pPage->pBt->mutex) );
pInfo->pCell = pCell;
assert( pPage->leaf==0 || pPage->leaf==1 ); assert( pPage->leaf==0 || pPage->leaf==1 );
n = pPage->childPtrSize;
assert( n==4-4*pPage->leaf );
if( pPage->intKey ){ if( pPage->intKey ){
if( pPage->hasData ){ if( pPage->hasData ){
assert( n==0 ); assert( pIter==pCell );
n = getVarint32(pCell, nPayload); pIter += getVarint32(pIter, nPayload);
}else{ }else{
nPayload = 0; nPayload = 0;
} }
n += getVarint(&pCell[n], (u64*)&pInfo->nKey); pIter += getVarint(pIter, (u64*)&pInfo->nKey);
pInfo->nData = nPayload;
}else{ }else{
pInfo->nData = 0; pIter += getVarint32(pIter, nPayload);
n += getVarint32(&pCell[n], nPayload);
pInfo->nKey = nPayload; pInfo->nKey = nPayload;
} }
pInfo->nPayload = nPayload; pInfo->nPayload = nPayload;
pInfo->nHeader = n; pInfo->pPayload = pIter;
testcase( nPayload==pPage->maxLocal ); testcase( nPayload==pPage->maxLocal );
testcase( nPayload==pPage->maxLocal+1 ); testcase( nPayload==pPage->maxLocal+1 );
if( likely(nPayload<=pPage->maxLocal) ){ if( nPayload<=pPage->maxLocal ){
/* This is the (easy) common case where the entire payload fits /* This is the (easy) common case where the entire payload fits
** on the local page. No overflow is required. ** on the local page. No overflow is required.
*/ */
if( (pInfo->nSize = (u16)(n+nPayload))<4 ) pInfo->nSize = 4; pInfo->nSize = nPayload + (u16)(pIter - pCell);
if( pInfo->nSize<4 ) pInfo->nSize = 4;
pInfo->nLocal = (u16)nPayload; pInfo->nLocal = (u16)nPayload;
pInfo->iOverflow = 0; pInfo->iOverflow = 0;
}else{ }else{
@ -1035,7 +1030,7 @@ static void btreeParseCellPtr(
}else{ }else{
pInfo->nLocal = (u16)minLocal; pInfo->nLocal = (u16)minLocal;
} }
pInfo->iOverflow = (u16)(pInfo->nLocal + n); pInfo->iOverflow = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell);
pInfo->nSize = pInfo->iOverflow + 4; pInfo->nSize = pInfo->iOverflow + 4;
} }
} }
@ -1132,7 +1127,6 @@ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
if( *pRC ) return; if( *pRC ) return;
assert( pCell!=0 ); assert( pCell!=0 );
btreeParseCellPtr(pPage, pCell, &info); btreeParseCellPtr(pPage, pCell, &info);
assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
if( info.iOverflow ){ if( info.iOverflow ){
Pgno ovfl = get4byte(&pCell[info.iOverflow]); Pgno ovfl = get4byte(&pCell[info.iOverflow]);
ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC); ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
@ -3866,8 +3860,9 @@ int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){ int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
assert( cursorHoldsMutex(pCur) ); assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID ); assert( pCur->eState==CURSOR_VALID );
assert( pCur->apPage[pCur->iPage]->intKey==1 );
getCellInfo(pCur); getCellInfo(pCur);
*pSize = pCur->info.nData; *pSize = pCur->info.nPayload;
return SQLITE_OK; return SQLITE_OK;
} }
@ -4018,7 +4013,6 @@ static int accessPayload(
){ ){
unsigned char *aPayload; unsigned char *aPayload;
int rc = SQLITE_OK; int rc = SQLITE_OK;
u32 nKey;
int iIdx = 0; int iIdx = 0;
MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */ MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */ BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */
@ -4033,15 +4027,13 @@ static int accessPayload(
assert( eOp!=2 || offset==0 ); /* Always start from beginning for eOp==2 */ assert( eOp!=2 || offset==0 ); /* Always start from beginning for eOp==2 */
getCellInfo(pCur); getCellInfo(pCur);
aPayload = pCur->info.pCell + pCur->info.nHeader; aPayload = pCur->info.pPayload;
nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey);
#ifdef SQLITE_DIRECT_OVERFLOW_READ #ifdef SQLITE_DIRECT_OVERFLOW_READ
bEnd = (offset+amt==nKey+pCur->info.nData); bEnd = offset+amt==pCur->info.nPayload;
#endif #endif
assert( offset+amt <= pCur->info.nPayload );
if( NEVER(offset+amt > nKey+pCur->info.nData) if( &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] ){
|| &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
){
/* Trying to read or write past the end of the data is an error */ /* Trying to read or write past the end of the data is an error */
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_BKPT;
} }
@ -4275,7 +4267,7 @@ static const void *fetchPayload(
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell ); assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
assert( pCur->info.nSize>0 ); assert( pCur->info.nSize>0 );
*pAmt = pCur->info.nLocal; *pAmt = pCur->info.nLocal;
return (void*)(pCur->info.pCell + pCur->info.nHeader); return (void*)pCur->info.pPayload;
} }
@ -5640,9 +5632,10 @@ static int fillInCell(
} }
nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey); nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey);
btreeParseCellPtr(pPage, pCell, &info); btreeParseCellPtr(pPage, pCell, &info);
assert( info.nHeader==nHeader ); assert( nHeader=(int)(info.pPayload - pCell) );
assert( info.nKey==nKey ); assert( info.nKey==nKey );
assert( info.nData==(u32)(nData+nZero) ); assert( pPage->intKey==0 || info.nPayload==(u32)(nData+nZero) );
assert( pPage->intKey==1 || info.nPayload==nKey );
/* Fill in the payload */ /* Fill in the payload */
nPayload = nData + nZero; nPayload = nData + nZero;
@ -8086,19 +8079,18 @@ static int checkTreePage(
"On tree page %d cell %d: ", iPage, i); "On tree page %d cell %d: ", iPage, i);
pCell = findCell(pPage,i); pCell = findCell(pPage,i);
btreeParseCellPtr(pPage, pCell, &info); btreeParseCellPtr(pPage, pCell, &info);
sz = info.nData; sz = info.nPayload;
if( !pPage->intKey ) sz += (int)info.nKey;
/* For intKey pages, check that the keys are in order. /* For intKey pages, check that the keys are in order.
*/ */
else if( i==0 ) nMinKey = nMaxKey = info.nKey; if( pPage->intKey ){
else{ if( i==0 ){
if( info.nKey <= nMaxKey ){ nMinKey = nMaxKey = info.nKey;
}else if( info.nKey <= nMaxKey ){
checkAppendMsg(pCheck, zContext, checkAppendMsg(pCheck, zContext,
"Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey); "Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey);
} }
nMaxKey = info.nKey; nMaxKey = info.nKey;
} }
assert( sz==info.nPayload );
if( (sz>info.nLocal) if( (sz>info.nLocal)
&& (&pCell[info.iOverflow]<=&pPage->aData[pBt->usableSize]) && (&pCell[info.iOverflow]<=&pPage->aData[pBt->usableSize])
){ ){

View File

@ -456,12 +456,10 @@ struct BtShared {
*/ */
typedef struct CellInfo CellInfo; typedef struct CellInfo CellInfo;
struct CellInfo { struct CellInfo {
i64 nKey; /* The key for INTKEY tables, or number of bytes in key */ i64 nKey; /* The key for INTKEY tables, or nPayload otherwise */
u8 *pCell; /* Pointer to the start of cell content */ u8 *pPayload; /* Pointer to the start of payload */
u32 nData; /* Number of bytes of data */ u32 nPayload; /* Bytes of payload */
u32 nPayload; /* Total amount of payload */ u16 nLocal; /* Amount of payload held locally, not on overflow */
u16 nHeader; /* Size of the cell content header in bytes */
u16 nLocal; /* Amount of payload held locally */
u16 iOverflow; /* Offset to overflow page number. Zero if no overflow */ u16 iOverflow; /* Offset to overflow page number. Zero if no overflow */
u16 nSize; /* Size of the cell content on the main b-tree page */ u16 nSize; /* Size of the cell content on the main b-tree page */
}; };