aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2022-03-29 13:16:32 +0000
committerdrh <>2022-03-29 13:16:32 +0000
commitde9484858e8cbf66bf86e27f2e4a31cfde641d35 (patch)
tree278337bf816b7c2d4a188ecdad1f46dbf9030d1a /src
parentfb92e071861384455519a718706d217c4e91a7d6 (diff)
downloadsqlite-de9484858e8cbf66bf86e27f2e4a31cfde641d35.tar.gz
sqlite-de9484858e8cbf66bf86e27f2e4a31cfde641d35.zip
Avoid unnecessary calls to balance() from sqlite3BtreeDelete().
FossilOrigin-Name: d0966d1bdd474e27cb048884d340184f0e81a4fab65eb6b74682b20630caddf8
Diffstat (limited to 'src')
-rw-r--r--src/btree.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/src/btree.c b/src/btree.c
index d31d30c5e..d4cd0d020 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -8742,7 +8742,6 @@ static int anotherValidCursor(BtCursor *pCur){
*/
static int balance(BtCursor *pCur){
int rc = SQLITE_OK;
- const int nMin = pCur->pBt->usableSize * 2 / 3;
u8 aBalanceQuickSpace[13];
u8 *pFree = 0;
@@ -8754,7 +8753,11 @@ static int balance(BtCursor *pCur){
MemPage *pPage = pCur->pPage;
if( NEVER(pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break;
- if( pPage->nOverflow==0 && pPage->nFree<=nMin ){
+ if( pPage->nOverflow==0 && pPage->nFree*3<=pCur->pBt->usableSize*2 ){
+ /* No rebalance required as long as:
+ ** (1) There are no overflow cells
+ ** (2) The amount of free space on the page is less than 2/3rds of
+ ** the total usable space on the page. */
break;
}else if( (iPage = pCur->iPage)==0 ){
if( pPage->nOverflow && (rc = anotherValidCursor(pCur))==SQLITE_OK ){
@@ -9568,7 +9571,15 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
** been corrected, so be it. Otherwise, after balancing the leaf node,
** walk the cursor up the tree to the internal node and balance it as
** well. */
- rc = balance(pCur);
+ assert( pCur->pPage->nOverflow==0 );
+ assert( pCur->pPage->nFree>=0 );
+ if( pCur->pPage->nFree*3<=pCur->pBt->usableSize*2 ){
+ /* Optimization: If the free space is less than 2/3rds of the page,
+ ** then balance() will always be a no-op. No need to invoke it. */
+ rc = SQLITE_OK;
+ }else{
+ rc = balance(pCur);
+ }
if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){
releasePageNotNull(pCur->pPage);
pCur->iPage--;