From d720d394d0b85ebd26f316ea1e34477db2574405 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 7 May 2018 17:27:04 +0000 Subject: [PATCH] Improved comments on the cell-overwrite optimization code. FossilOrigin-Name: a4fe966da2fc479b18bf521ff596000410af3a611f7d8723d126795e595ccf22 --- manifest | 13 +++++---- manifest.uuid | 2 +- src/btree.c | 73 +++++++++++++++++++++++++++++++++++---------------- 3 files changed, 57 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 6862957f3f..8b8e5d6d37 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C On\san\sUPDATE,\stry\sto\soverwrite\san\sexisting\sbtree\scell\swith\sthe\smodified\ncontent,\sif\sthe\sold\sand\snew\scell\sare\sthe\ssame\ssize.\s\sUse\smemcmp()\sfirst\nto\savoid\sdirtying\spages\sthat\sare\sunchanged. -D 2018-05-07T11:48:22.641 +C Improved\scomments\son\sthe\scell-overwrite\soptimization\scode. +D 2018-05-07T17:27:04.995 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 5ce9343cba9c189046f1afe6d2bcc1f68079439febc05267b98aec6ecc752439 @@ -434,7 +434,7 @@ F src/auth.c 6277d63837357549fe14e723490d6dc1a38768d71c795c5eb5c0f8a99f918f73 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 6be0267a7da8ca04c466094ca9d9a8a26333e175cff794afe5138aeec0cdb7c2 +F src/btree.c 7b21976dc09778f05af0e085c40b735467ffdcea64bd07dace3f12ca0a2defce F src/btree.h 0866c0a08255142ea0e754aabd211c843cab32045c978a592a43152405ed0c84 F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96 F src/build.c 0c2be5839f22aa2938f217c6c6c2120d9fc96872a546a37541a8271541cb355e @@ -1727,8 +1727,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 374d8e264487b0437a8d995ced1bc026a92d495a2d0568f65f033e9ebe11d0e2 3e11dc3183bc3e8ec49af244a8e8b3e07d12f7a2e59028b2bf64ce0ab589a91f -R 891ce8c2c78f1f487f80460b8c248fd0 -T +closed 3e11dc3183bc3e8ec49af244a8e8b3e07d12f7a2e59028b2bf64ce0ab589a91f +P 5887d8beb502ad62689d31b850f46ab50831a1e9db36adf20d55ad45619d207e +R e6599f47435d4296a22afaa3f1649f4a U drh -Z 7955ef5d032aea210d99e8bc24e906bc +Z 8048adc03c51022109ca997ec38e8ad8 diff --git a/manifest.uuid b/manifest.uuid index 3fa7a09c8a..91ceb15d7a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5887d8beb502ad62689d31b850f46ab50831a1e9db36adf20d55ad45619d207e \ No newline at end of file +a4fe966da2fc479b18bf521ff596000410af3a611f7d8723d126795e595ccf22 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 4d83d2e4de..60635172c4 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8332,43 +8332,70 @@ int sqlite3BtreeInsert( invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0); /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing - ** to a row with the same key as the new entry being inserted. */ - assert( (flags & BTREE_SAVEPOSITION)==0 || - ((pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey) ); + ** to a row with the same key as the new entry being inserted. + */ +#ifdef SQLITE_DEBUG + if( flags & BTREE_SAVEPOSITION ){ + assert( pCur->curFlags & BTCF_ValidNKey ); + assert( pX->nKey==pCur->info.nKey ); + assert( pCur->info.nSize!=0 ); + assert( loc==0 ); + } +#endif - /* If the cursor is currently on the last row and we are appending a - ** new row onto the end, set the "loc" to avoid an unnecessary - ** btreeMoveto() call */ + /* On the other hand, BTREE_SAVEPOSITION==0 does not imply + ** that the cursor is not pointing to a row to be overwritten. + ** So do a complete check. + */ if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){ - /* The current is currently pointing to the entry that is to be + /* The cursor is pointing to the entry that is to be ** overwritten */ assert( pX->nData>=0 && pX->nZero>=0 ); if( pCur->info.nSize!=0 && pCur->info.nPayload==(u32)pX->nData+pX->nZero ){ + /* New entry is the same size as the old. Do an overwrite */ return btreeOverwriteCell(pCur, pX); } - loc = 0; + assert( loc==0 ); }else if( loc==0 ){ + /* The cursor is *not* pointing to the cell to be overwritten, nor + ** to an adjacent cell. Move the cursor so that it is pointing either + ** to the cell to be overwritten or an adjacent cell. + */ rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc); if( rc ) return rc; } - }else if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){ - if( pX->nMem ){ - UnpackedRecord r; - r.pKeyInfo = pCur->pKeyInfo; - r.aMem = pX->aMem; - r.nField = pX->nMem; - r.default_rc = 0; - r.errCode = 0; - r.r1 = 0; - r.r2 = 0; - r.eqSeen = 0; - rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc); - }else{ - rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc); + }else{ + /* This is an index or a WITHOUT ROWID table */ + + /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing + ** to a row with the same key as the new entry being inserted. + */ + assert( (flags & BTREE_SAVEPOSITION)==0 || loc==0 ); + + /* If the cursor is not already pointing either to the cell to be + ** overwritten, or if a new cell is being inserted, if the cursor is + ** not pointing to an immediately adjacent cell, then move the cursor + ** so that it does. + */ + if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){ + if( pX->nMem ){ + UnpackedRecord r; + r.pKeyInfo = pCur->pKeyInfo; + r.aMem = pX->aMem; + r.nField = pX->nMem; + r.default_rc = 0; + r.errCode = 0; + r.r1 = 0; + r.r2 = 0; + r.eqSeen = 0; + rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc); + }else{ + rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc); + } + if( rc ) return rc; } - if( rc ) return rc; } assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) );