aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2022-01-02 14:55:43 +0000
committerdrh <>2022-01-02 14:55:43 +0000
commit7e17a3abbe7f1b644661c7e5ededd4679dd1b409 (patch)
tree5019098db924680fe01a53bc17b42997cf368f75 /src
parent44a5c0257f8bcfd164472b34cf8c38e9a228c9a1 (diff)
downloadsqlite-7e17a3abbe7f1b644661c7e5ededd4679dd1b409.tar.gz
sqlite-7e17a3abbe7f1b644661c7e5ededd4679dd1b409.zip
Small performance optimization and size reduction in sqlite3BtreeDelete().
FossilOrigin-Name: da0af4dd9ba4180a16543fac1549fd4ccecdc66dcf6d275f77de21fd80708882
Diffstat (limited to 'src')
-rw-r--r--src/btree.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/src/btree.c b/src/btree.c
index cfaffb7d7..4f777f0f7 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -9229,14 +9229,13 @@ int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){
int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
Btree *p = pCur->pBtree;
BtShared *pBt = p->pBt;
- int rc; /* Return code */
- MemPage *pPage; /* Page to delete cell from */
- unsigned char *pCell; /* Pointer to cell to delete */
- int iCellIdx; /* Index of cell to delete */
- int iCellDepth; /* Depth of node containing pCell */
- CellInfo info; /* Size of the cell being deleted */
- int bSkipnext = 0; /* Leaf cursor in SKIPNEXT state */
- u8 bPreserve = flags & BTREE_SAVEPOSITION; /* Keep cursor valid */
+ int rc; /* Return code */
+ MemPage *pPage; /* Page to delete cell from */
+ unsigned char *pCell; /* Pointer to cell to delete */
+ int iCellIdx; /* Index of cell to delete */
+ int iCellDepth; /* Depth of node containing pCell */
+ CellInfo info; /* Size of the cell being deleted */
+ u8 bPreserve; /* Keep cursor valid. 2 for CURSOR_SKIPNEXT */
assert( cursorOwnsBtShared(pCur) );
assert( pBt->inTransaction==TRANS_WRITE );
@@ -9255,23 +9254,31 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
iCellDepth = pCur->iPage;
iCellIdx = pCur->ix;
pPage = pCur->pPage;
- pCell = findCell(pPage, iCellIdx);
- if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){
+ if( pPage->nCell<=iCellIdx ){
return SQLITE_CORRUPT_BKPT;
}
- if( pPage->nCell<=iCellIdx ){
+ pCell = findCell(pPage, iCellIdx);
+ if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){
return SQLITE_CORRUPT_BKPT;
}
- /* If the bPreserve flag is set to true, then the cursor position must
+ /* If the BTREE_SAVEPOSITION bit is on, then the cursor position must
** be preserved following this delete operation. If the current delete
** will cause a b-tree rebalance, then this is done by saving the cursor
** key and leaving the cursor in CURSOR_REQUIRESEEK state before
** returning.
**
- ** Or, if the current delete will not cause a rebalance, then the cursor
+ ** If the current delete will not cause a rebalance, then the cursor
** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
- ** before or after the deleted entry. In this case set bSkipnext to true. */
+ ** before or after the deleted entry.
+ **
+ ** The bPreserve value records which path is required:
+ **
+ ** bPreserve==0 Not necessary to save the cursor position
+ ** bPreserve==1 Use CURSOR_REQUIRESEEK to save the cursor position
+ ** bPreserve==2 Cursor won't move. Set CURSOR_SKIPNEXT.
+ */
+ bPreserve = (flags & BTREE_SAVEPOSITION)!=0;
if( bPreserve ){
if( !pPage->leaf
|| (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
@@ -9282,7 +9289,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
rc = saveCursorKey(pCur);
if( rc ) return rc;
}else{
- bSkipnext = 1;
+ bPreserve = 2;
}
}
@@ -9382,8 +9389,8 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
}
if( rc==SQLITE_OK ){
- if( bSkipnext ){
- assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) );
+ if( bPreserve>1 ){
+ assert( (pCur->iPage==iCellDepth || CORRUPT_DB) );
assert( pPage==pCur->pPage || CORRUPT_DB );
assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell );
pCur->eState = CURSOR_SKIPNEXT;