mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Add the MemPage.xParseCell method and provide various implementations
(variations on the former btreeParseCellPtr()) depending on the page type. FossilOrigin-Name: 41d03d883c4f7ca279eb9dd679f3ab81c8d957d9
This commit is contained in:
14
manifest
14
manifest
@@ -1,5 +1,5 @@
|
|||||||
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.
|
C Add\sthe\sMemPage.xParseCell\smethod\sand\sprovide\svarious\simplementations\n(variations\son\sthe\sformer\sbtreeParseCellPtr())\sdepending\son\sthe\spage\stype.
|
||||||
D 2015-06-19T15:07:14.566
|
D 2015-06-19T17:19:34.228
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 1063c58075b7400d93326b0eb332b48a54f53025
|
F Makefile.in 1063c58075b7400d93326b0eb332b48a54f53025
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -192,9 +192,9 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
|||||||
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
|
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
|
||||||
F src/bitvec.c 5eb7958c3bf65210211cbcfc44eff86d0ded7c9d
|
F src/bitvec.c 5eb7958c3bf65210211cbcfc44eff86d0ded7c9d
|
||||||
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
||||||
F src/btree.c 960e66f4a9fd494c5712f4342432a2fb1cbb72c1
|
F src/btree.c cf8310b4429e5f0400868b598d75d414b32da98e
|
||||||
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
||||||
F src/btreeInt.h 97901d5434a22344cd5ae47e80ed677bd21d572d
|
F src/btreeInt.h 6ece2dd9c8e2eac05f0a8ded8772a44e96486c65
|
||||||
F src/build.c b3f15255d5b16e42dafeaa638fd4f8a47c94ed70
|
F src/build.c b3f15255d5b16e42dafeaa638fd4f8a47c94ed70
|
||||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||||
F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575
|
F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575
|
||||||
@@ -1286,7 +1286,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P 9246eca54adaee571dab0c066afaa604fcf9c44f
|
P 02f7e9d7d7b93d0b6bbd6cc0d0359b3b741b9931
|
||||||
R 65525ba5a493bb8d3d370265d6f2abe8
|
R 2f4b41ef502fc9cfa753afb16ada8794
|
||||||
U drh
|
U drh
|
||||||
Z b80278f806bcab0592c2162609b43f46
|
Z a171034151748a0b17304cc3b38b62ab
|
||||||
|
@@ -1 +1 @@
|
|||||||
02f7e9d7d7b93d0b6bbd6cc0d0359b3b741b9931
|
41d03d883c4f7ca279eb9dd679f3ab81c8d957d9
|
190
src/btree.c
190
src/btree.c
@@ -980,11 +980,73 @@ static u8 *findOverflowCell(MemPage *pPage, int iCell){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Parse a cell content block and fill in the CellInfo structure. There
|
** This is common tail processing for btreeParseCellPtr() and
|
||||||
** are two versions of this function. btreeParseCell() takes a
|
** btreeParseCellPtrIndex() for the case when the cell does not fit entirely
|
||||||
** cell index as the second argument and btreeParseCellPtr()
|
** on a single B-tree page. Make necessary adjustments to the CellInfo
|
||||||
** takes a pointer to the body of the cell as its second argument.
|
** structure.
|
||||||
*/
|
*/
|
||||||
|
static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow(
|
||||||
|
MemPage *pPage, /* Page containing the cell */
|
||||||
|
u8 *pCell, /* Pointer to the cell text. */
|
||||||
|
CellInfo *pInfo /* Fill in this structure */
|
||||||
|
){
|
||||||
|
/* If the payload will not fit completely on the local page, we have
|
||||||
|
** to decide how much to store locally and how much to spill onto
|
||||||
|
** overflow pages. The strategy is to minimize the amount of unused
|
||||||
|
** space on overflow pages while keeping the amount of local storage
|
||||||
|
** in between minLocal and maxLocal.
|
||||||
|
**
|
||||||
|
** Warning: changing the way overflow payload is distributed in any
|
||||||
|
** way will result in an incompatible file format.
|
||||||
|
*/
|
||||||
|
int minLocal; /* Minimum amount of payload held locally */
|
||||||
|
int maxLocal; /* Maximum amount of payload held locally */
|
||||||
|
int surplus; /* Overflow payload available for local storage */
|
||||||
|
|
||||||
|
minLocal = pPage->minLocal;
|
||||||
|
maxLocal = pPage->maxLocal;
|
||||||
|
surplus = minLocal + (pInfo->nPayload - minLocal)%(pPage->pBt->usableSize-4);
|
||||||
|
testcase( surplus==maxLocal );
|
||||||
|
testcase( surplus==maxLocal+1 );
|
||||||
|
if( surplus <= maxLocal ){
|
||||||
|
pInfo->nLocal = (u16)surplus;
|
||||||
|
}else{
|
||||||
|
pInfo->nLocal = (u16)minLocal;
|
||||||
|
}
|
||||||
|
pInfo->iOverflow = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell);
|
||||||
|
pInfo->nSize = pInfo->iOverflow + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The following routines are implementations of the MemPage.xParseCell()
|
||||||
|
** method.
|
||||||
|
**
|
||||||
|
** Parse a cell content block and fill in the CellInfo structure.
|
||||||
|
**
|
||||||
|
** btreeParseCellPtr() => table btree leaf nodes
|
||||||
|
** btreeParseCellNoPayload() => table btree internal nodes
|
||||||
|
** btreeParseCellPtrIndex() => index btree nodes
|
||||||
|
**
|
||||||
|
** There is also a wrapper function btreeParseCell() that works for
|
||||||
|
** all MemPage types and that references the cell by index rather than
|
||||||
|
** by pointer.
|
||||||
|
*/
|
||||||
|
static void btreeParseCellPtrNoPayload(
|
||||||
|
MemPage *pPage, /* Page containing the cell */
|
||||||
|
u8 *pCell, /* Pointer to the cell text. */
|
||||||
|
CellInfo *pInfo /* Fill in this structure */
|
||||||
|
){
|
||||||
|
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
|
||||||
|
assert( pPage->leaf==0 );
|
||||||
|
assert( pPage->noPayload );
|
||||||
|
assert( pPage->childPtrSize==4 );
|
||||||
|
pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey);
|
||||||
|
pInfo->nPayload = 0;
|
||||||
|
pInfo->nLocal = 0;
|
||||||
|
pInfo->iOverflow = 0;
|
||||||
|
pInfo->pPayload = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
static void btreeParseCellPtr(
|
static void btreeParseCellPtr(
|
||||||
MemPage *pPage, /* Page containing the cell */
|
MemPage *pPage, /* Page containing the cell */
|
||||||
u8 *pCell, /* Pointer to the cell text. */
|
u8 *pCell, /* Pointer to the cell text. */
|
||||||
@@ -995,23 +1057,12 @@ static void btreeParseCellPtr(
|
|||||||
|
|
||||||
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
|
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
|
||||||
assert( pPage->leaf==0 || pPage->leaf==1 );
|
assert( pPage->leaf==0 || pPage->leaf==1 );
|
||||||
if( pPage->intKeyLeaf ){
|
assert( pPage->intKeyLeaf || pPage->noPayload );
|
||||||
assert( pPage->childPtrSize==0 );
|
assert( pPage->noPayload==0 );
|
||||||
pIter = pCell + getVarint32(pCell, nPayload);
|
assert( pPage->intKeyLeaf );
|
||||||
pIter += getVarint(pIter, (u64*)&pInfo->nKey);
|
assert( pPage->childPtrSize==0 );
|
||||||
}else if( pPage->noPayload ){
|
pIter = pCell + getVarint32(pCell, nPayload);
|
||||||
assert( pPage->childPtrSize==4 );
|
pIter += getVarint(pIter, (u64*)&pInfo->nKey);
|
||||||
pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey);
|
|
||||||
pInfo->nPayload = 0;
|
|
||||||
pInfo->nLocal = 0;
|
|
||||||
pInfo->iOverflow = 0;
|
|
||||||
pInfo->pPayload = 0;
|
|
||||||
return;
|
|
||||||
}else{
|
|
||||||
pIter = pCell + pPage->childPtrSize;
|
|
||||||
pIter += getVarint32(pIter, nPayload);
|
|
||||||
pInfo->nKey = nPayload;
|
|
||||||
}
|
|
||||||
pInfo->nPayload = nPayload;
|
pInfo->nPayload = nPayload;
|
||||||
pInfo->pPayload = pIter;
|
pInfo->pPayload = pIter;
|
||||||
testcase( nPayload==pPage->maxLocal );
|
testcase( nPayload==pPage->maxLocal );
|
||||||
@@ -1025,31 +1076,46 @@ static void btreeParseCellPtr(
|
|||||||
pInfo->nLocal = (u16)nPayload;
|
pInfo->nLocal = (u16)nPayload;
|
||||||
pInfo->iOverflow = 0;
|
pInfo->iOverflow = 0;
|
||||||
}else{
|
}else{
|
||||||
/* If the payload will not fit completely on the local page, we have
|
btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo);
|
||||||
** to decide how much to store locally and how much to spill onto
|
}
|
||||||
** overflow pages. The strategy is to minimize the amount of unused
|
}
|
||||||
** space on overflow pages while keeping the amount of local storage
|
static void btreeParseCellPtrIndex(
|
||||||
** in between minLocal and maxLocal.
|
MemPage *pPage, /* Page containing the cell */
|
||||||
**
|
u8 *pCell, /* Pointer to the cell text. */
|
||||||
** Warning: changing the way overflow payload is distributed in any
|
CellInfo *pInfo /* Fill in this structure */
|
||||||
** way will result in an incompatible file format.
|
){
|
||||||
*/
|
u8 *pIter; /* For scanning through pCell */
|
||||||
int minLocal; /* Minimum amount of payload held locally */
|
u32 nPayload; /* Number of bytes of cell payload */
|
||||||
int maxLocal; /* Maximum amount of payload held locally */
|
|
||||||
int surplus; /* Overflow payload available for local storage */
|
|
||||||
|
|
||||||
minLocal = pPage->minLocal;
|
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
|
||||||
maxLocal = pPage->maxLocal;
|
assert( pPage->leaf==0 || pPage->leaf==1 );
|
||||||
surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize - 4);
|
assert( pPage->intKeyLeaf==0 );
|
||||||
testcase( surplus==maxLocal );
|
assert( pPage->noPayload==0 );
|
||||||
testcase( surplus==maxLocal+1 );
|
pIter = pCell + pPage->childPtrSize;
|
||||||
if( surplus <= maxLocal ){
|
nPayload = *pIter;
|
||||||
pInfo->nLocal = (u16)surplus;
|
if( nPayload>=0x80 ){
|
||||||
}else{
|
u8 *pEnd = &pIter[9];
|
||||||
pInfo->nLocal = (u16)minLocal;
|
nPayload &= 0x7f;
|
||||||
}
|
do{
|
||||||
pInfo->iOverflow = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell);
|
nPayload = (nPayload<<7) | (*++pIter & 0x7f);
|
||||||
pInfo->nSize = pInfo->iOverflow + 4;
|
}while( *(pIter)>=0x80 && pIter<pEnd );
|
||||||
|
}
|
||||||
|
pIter++;
|
||||||
|
pInfo->nKey = nPayload;
|
||||||
|
pInfo->nPayload = nPayload;
|
||||||
|
pInfo->pPayload = pIter;
|
||||||
|
testcase( nPayload==pPage->maxLocal );
|
||||||
|
testcase( nPayload==pPage->maxLocal+1 );
|
||||||
|
if( nPayload<=pPage->maxLocal ){
|
||||||
|
/* This is the (easy) common case where the entire payload fits
|
||||||
|
** on the local page. No overflow is required.
|
||||||
|
*/
|
||||||
|
pInfo->nSize = nPayload + (u16)(pIter - pCell);
|
||||||
|
if( pInfo->nSize<4 ) pInfo->nSize = 4;
|
||||||
|
pInfo->nLocal = (u16)nPayload;
|
||||||
|
pInfo->iOverflow = 0;
|
||||||
|
}else{
|
||||||
|
btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void btreeParseCell(
|
static void btreeParseCell(
|
||||||
@@ -1057,19 +1123,20 @@ static void btreeParseCell(
|
|||||||
int iCell, /* The cell index. First cell is 0 */
|
int iCell, /* The cell index. First cell is 0 */
|
||||||
CellInfo *pInfo /* Fill in this structure */
|
CellInfo *pInfo /* Fill in this structure */
|
||||||
){
|
){
|
||||||
btreeParseCellPtr(pPage, findCell(pPage, iCell), pInfo);
|
pPage->xParseCell(pPage, findCell(pPage, iCell), pInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
** The following routines are implementations of the MemPage.xCellSize
|
||||||
|
** method.
|
||||||
|
**
|
||||||
** Compute the total number of bytes that a Cell needs in the cell
|
** Compute the total number of bytes that a Cell needs in the cell
|
||||||
** data area of the btree-page. The return number includes the cell
|
** data area of the btree-page. The return number includes the cell
|
||||||
** data header and the local payload, but not any overflow page or
|
** data header and the local payload, but not any overflow page or
|
||||||
** the space used by the cell pointer.
|
** the space used by the cell pointer.
|
||||||
**
|
**
|
||||||
** The first implementation, cellSizePtr(), handles pages that contain
|
** cellSizePtrNoPayload() => table internal nodes
|
||||||
** payload, which is to say all index pages and left table pages. The
|
** cellSizePtr() => all index nodes & table leaf nodes
|
||||||
** second cellSizePtrNoPayload() implemention is a high-speed version
|
|
||||||
** for pages that contain no payload - internal table pages.
|
|
||||||
*/
|
*/
|
||||||
static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
|
static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
|
||||||
u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */
|
u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */
|
||||||
@@ -1082,7 +1149,7 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
|
|||||||
** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
|
** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
|
||||||
** this function verifies that this invariant is not violated. */
|
** this function verifies that this invariant is not violated. */
|
||||||
CellInfo debuginfo;
|
CellInfo debuginfo;
|
||||||
btreeParseCellPtr(pPage, pCell, &debuginfo);
|
pPage->xParseCell(pPage, pCell, &debuginfo);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert( pPage->noPayload==0 );
|
assert( pPage->noPayload==0 );
|
||||||
@@ -1130,7 +1197,7 @@ static u16 cellSizePtrNoPayload(MemPage *pPage, u8 *pCell){
|
|||||||
** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
|
** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
|
||||||
** this function verifies that this invariant is not violated. */
|
** this function verifies that this invariant is not violated. */
|
||||||
CellInfo debuginfo;
|
CellInfo debuginfo;
|
||||||
btreeParseCellPtr(pPage, pCell, &debuginfo);
|
pPage->xParseCell(pPage, pCell, &debuginfo);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert( pPage->childPtrSize==4 );
|
assert( pPage->childPtrSize==4 );
|
||||||
@@ -1159,7 +1226,7 @@ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
|
|||||||
CellInfo info;
|
CellInfo info;
|
||||||
if( *pRC ) return;
|
if( *pRC ) return;
|
||||||
assert( pCell!=0 );
|
assert( pCell!=0 );
|
||||||
btreeParseCellPtr(pPage, pCell, &info);
|
pPage->xParseCell(pPage, pCell, &info);
|
||||||
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);
|
||||||
@@ -1540,10 +1607,12 @@ static int decodeFlags(MemPage *pPage, int flagByte){
|
|||||||
if( pPage->leaf ){
|
if( pPage->leaf ){
|
||||||
pPage->intKeyLeaf = 1;
|
pPage->intKeyLeaf = 1;
|
||||||
pPage->noPayload = 0;
|
pPage->noPayload = 0;
|
||||||
|
pPage->xParseCell = btreeParseCellPtr;
|
||||||
}else{
|
}else{
|
||||||
pPage->intKeyLeaf = 0;
|
pPage->intKeyLeaf = 0;
|
||||||
pPage->noPayload = 1;
|
pPage->noPayload = 1;
|
||||||
pPage->xCellSize = cellSizePtrNoPayload;
|
pPage->xCellSize = cellSizePtrNoPayload;
|
||||||
|
pPage->xParseCell = btreeParseCellPtrNoPayload;
|
||||||
}
|
}
|
||||||
pPage->maxLocal = pBt->maxLeaf;
|
pPage->maxLocal = pBt->maxLeaf;
|
||||||
pPage->minLocal = pBt->minLeaf;
|
pPage->minLocal = pBt->minLeaf;
|
||||||
@@ -1557,6 +1626,7 @@ static int decodeFlags(MemPage *pPage, int flagByte){
|
|||||||
pPage->intKey = 0;
|
pPage->intKey = 0;
|
||||||
pPage->intKeyLeaf = 0;
|
pPage->intKeyLeaf = 0;
|
||||||
pPage->noPayload = 0;
|
pPage->noPayload = 0;
|
||||||
|
pPage->xParseCell = btreeParseCellPtrIndex;
|
||||||
pPage->maxLocal = pBt->maxLocal;
|
pPage->maxLocal = pBt->maxLocal;
|
||||||
pPage->minLocal = pBt->minLocal;
|
pPage->minLocal = pBt->minLocal;
|
||||||
}else{
|
}else{
|
||||||
@@ -3147,7 +3217,7 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
|
|||||||
u8 *pCell = findCell(pPage, i);
|
u8 *pCell = findCell(pPage, i);
|
||||||
if( eType==PTRMAP_OVERFLOW1 ){
|
if( eType==PTRMAP_OVERFLOW1 ){
|
||||||
CellInfo info;
|
CellInfo info;
|
||||||
btreeParseCellPtr(pPage, pCell, &info);
|
pPage->xParseCell(pPage, pCell, &info);
|
||||||
if( info.iOverflow
|
if( info.iOverflow
|
||||||
&& pCell+info.iOverflow+3<=pPage->aData+pPage->maskPage
|
&& pCell+info.iOverflow+3<=pPage->aData+pPage->maskPage
|
||||||
&& iFrom==get4byte(&pCell[info.iOverflow])
|
&& iFrom==get4byte(&pCell[info.iOverflow])
|
||||||
@@ -4992,7 +5062,7 @@ int sqlite3BtreeMovetoUnpacked(
|
|||||||
** case this happens. */
|
** case this happens. */
|
||||||
void *pCellKey;
|
void *pCellKey;
|
||||||
u8 * const pCellBody = pCell - pPage->childPtrSize;
|
u8 * const pCellBody = pCell - pPage->childPtrSize;
|
||||||
btreeParseCellPtr(pPage, pCellBody, &pCur->info);
|
pPage->xParseCell(pPage, pCellBody, &pCur->info);
|
||||||
nCell = (int)pCur->info.nKey;
|
nCell = (int)pCur->info.nKey;
|
||||||
testcase( nCell<0 ); /* True if key size is 2^32 or more */
|
testcase( nCell<0 ); /* True if key size is 2^32 or more */
|
||||||
testcase( nCell==0 ); /* Invalid key size: 0x80 0x80 0x00 */
|
testcase( nCell==0 ); /* Invalid key size: 0x80 0x80 0x00 */
|
||||||
@@ -5781,7 +5851,7 @@ static int clearCell(
|
|||||||
u32 ovflPageSize;
|
u32 ovflPageSize;
|
||||||
|
|
||||||
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
|
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
|
||||||
btreeParseCellPtr(pPage, pCell, &info);
|
pPage->xParseCell(pPage, pCell, &info);
|
||||||
*pnSize = info.nSize;
|
*pnSize = info.nSize;
|
||||||
if( info.iOverflow==0 ){
|
if( info.iOverflow==0 ){
|
||||||
return SQLITE_OK; /* No overflow pages. Return without doing anything */
|
return SQLITE_OK; /* No overflow pages. Return without doing anything */
|
||||||
@@ -5935,7 +6005,7 @@ static int fillInCell(
|
|||||||
#if SQLITE_DEBUG
|
#if SQLITE_DEBUG
|
||||||
{
|
{
|
||||||
CellInfo info;
|
CellInfo info;
|
||||||
btreeParseCellPtr(pPage, pCell, &info);
|
pPage->xParseCell(pPage, pCell, &info);
|
||||||
assert( nHeader=(int)(info.pPayload - pCell) );
|
assert( nHeader=(int)(info.pPayload - pCell) );
|
||||||
assert( info.nKey==nKey );
|
assert( info.nKey==nKey );
|
||||||
assert( *pnSize == info.nSize );
|
assert( *pnSize == info.nSize );
|
||||||
@@ -6584,7 +6654,7 @@ static int ptrmapCheckPages(MemPage **apPage, int nPage){
|
|||||||
u8 *z;
|
u8 *z;
|
||||||
|
|
||||||
z = findCell(pPage, j);
|
z = findCell(pPage, j);
|
||||||
btreeParseCellPtr(pPage, z, &info);
|
pPage->xParseCell(pPage, z, &info);
|
||||||
if( info.iOverflow ){
|
if( info.iOverflow ){
|
||||||
Pgno ovfl = get4byte(&z[info.iOverflow]);
|
Pgno ovfl = get4byte(&z[info.iOverflow]);
|
||||||
ptrmapGet(pBt, ovfl, &e, &n);
|
ptrmapGet(pBt, ovfl, &e, &n);
|
||||||
@@ -7215,7 +7285,7 @@ static int balance_nonroot(
|
|||||||
*/
|
*/
|
||||||
CellInfo info;
|
CellInfo info;
|
||||||
j--;
|
j--;
|
||||||
btreeParseCellPtr(pNew, apCell[j], &info);
|
pNew->xParseCell(pNew, apCell[j], &info);
|
||||||
pCell = pTemp;
|
pCell = pTemp;
|
||||||
sz = 4 + putVarint(&pCell[4], info.nKey);
|
sz = 4 + putVarint(&pCell[4], info.nKey);
|
||||||
pTemp = 0;
|
pTemp = 0;
|
||||||
@@ -8715,7 +8785,7 @@ static int checkTreePage(
|
|||||||
pCheck->v1 = iPage;
|
pCheck->v1 = iPage;
|
||||||
pCheck->v2 = i;
|
pCheck->v2 = i;
|
||||||
pCell = findCell(pPage,i);
|
pCell = findCell(pPage,i);
|
||||||
btreeParseCellPtr(pPage, pCell, &info);
|
pPage->xParseCell(pPage, pCell, &info);
|
||||||
sz = info.nPayload;
|
sz = info.nPayload;
|
||||||
/* For intKey pages, check that the keys are in order.
|
/* For intKey pages, check that the keys are in order.
|
||||||
*/
|
*/
|
||||||
|
@@ -231,6 +231,7 @@
|
|||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
typedef struct MemPage MemPage;
|
typedef struct MemPage MemPage;
|
||||||
typedef struct BtLock BtLock;
|
typedef struct BtLock BtLock;
|
||||||
|
typedef struct CellInfo CellInfo;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This is a magic string that appears at the beginning of every
|
** This is a magic string that appears at the beginning of every
|
||||||
@@ -295,7 +296,8 @@ struct MemPage {
|
|||||||
u8 *aDataEnd; /* One byte past the end of usable data */
|
u8 *aDataEnd; /* One byte past the end of usable data */
|
||||||
u8 *aCellIdx; /* The cell index area */
|
u8 *aCellIdx; /* The cell index area */
|
||||||
DbPage *pDbPage; /* Pager page handle */
|
DbPage *pDbPage; /* Pager page handle */
|
||||||
u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */
|
u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */
|
||||||
|
void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */
|
||||||
Pgno pgno; /* Page number for this page */
|
Pgno pgno; /* Page number for this page */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -461,7 +463,6 @@ struct BtShared {
|
|||||||
** about a cell. The parseCellPtr() function fills in this structure
|
** about a cell. The parseCellPtr() function fills in this structure
|
||||||
** based on information extract from the raw disk page.
|
** based on information extract from the raw disk page.
|
||||||
*/
|
*/
|
||||||
typedef struct CellInfo CellInfo;
|
|
||||||
struct CellInfo {
|
struct CellInfo {
|
||||||
i64 nKey; /* The key for INTKEY tables, or nPayload otherwise */
|
i64 nKey; /* The key for INTKEY tables, or nPayload otherwise */
|
||||||
u8 *pPayload; /* Pointer to the start of payload */
|
u8 *pPayload; /* Pointer to the start of payload */
|
||||||
|
Reference in New Issue
Block a user