-C Add\sthe\s--pcachetrace\soption\sto\sthe\sCLI.
-D 2023-06-21T14:11:25.888
+C This\sis\sa\sfailed\sattempt\sto\soptimize\sthe\susage\sof\sthe\spage\scache\sin\nsqlite3BtreeIndexMoveto()\sby\sdeferring\scalls\sto\ssqlite3PagerUnref()\sfor\nchild\spages\sof\sthe\sbtree\suntil\swe\sare\ssure\sthose\spages\swill\snot\sbe\sreused.\nThe\scode\sdoes\snot\swork\sin\stwo\ssenses:\s\s(1)\s\sMany\stests\sstill\sfail.\n(2)\sThe\sperformance\sgain\sis\sless\sthan\s2\smillion\scycles\sand\sdoes\snot\sseem\nworth\sthe\sextra\srisk\sand\scomplication.
+D 2023-06-21T18:12:07.803
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
F src/bitvec.c 9eac5f42c11914d5ef00a75605bb205e934f435c579687f985f1f8b0995c8645
F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522
-F src/btree.c 481666a3dd26b1cb16a9e9baaa3f6b17cab52a1d7a5836e5dcf5b45b85d4a51d
+F src/btree.c 9a505e73aa1a7ce96c3e6b5480485a0bca83248c9e79f63f0481444b459e50a0
F src/btree.h aa354b9bad4120af71e214666b35132712b8f2ec11869cb2315c52c81fad45cc
F src/btreeInt.h 3b4eff7155c0cea6971dc51f62e3529934a15a6640ec607dd42a767e379cb3a9
F src/build.c a8ae3b32d9aa9bbd2c0e97d7c0dd80def9fbca408425de1608f57ee6f47f45f4
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P f94f3021cde1d46373ee8fc8e5028d7507a937240c59cf0d0d19ab22acbd3c41
-R d23fbd106a98c76f065fa8c0590bcfbb
+P 61dfa92b44ad38a7aac76a09e167819ce5d0acace3e06ba9ed17b3264cc043c1
+R 92ef9d4b2ad4bcd79b4a344e5a5e7673
+T *branch * pcache-opt
+T *sym-pcache-opt *
+T -sym-trunk *
U drh
-Z 6142bb2a618d1d23b62eb525e555db78
+Z 279ebc4b1e0c74835cf97ad5712d1d20
# Remove this line to create a well-formed Fossil manifest.
){
int rc;
RecordCompare xRecordCompare;
+ int bNeedUnref; /* Deferred Unref() calls for pCur->apPage[] */
assert( cursorOwnsBtShared(pCur) );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
if( !pCur->pPage->isInit ){
return SQLITE_CORRUPT_BKPT;
}
+ bNeedUnref = 0;
goto bypass_moveto_root; /* Start search on the current page */
}
pIdxKey->errCode = SQLITE_OK;
}
- rc = moveToRoot(pCur);
- if( rc ){
- if( rc==SQLITE_EMPTY ){
- assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
- *pRes = -1;
- return SQLITE_OK;
+ if( pCur->eState==CURSOR_VALID
+ && pCur->iPage>0
+ && pCur->apPage[0]->nCell>0
+ ){
+ /* This block is similar to moveToRoot() except that it does not
+ ** call releasePageNotNull() on the child pages found in the cursor.
+ ** The pCur->apPage[x] pointers for x>=1 up to x==bNeedUnref
+ ** remain valid and available for reuse. This means that the state of
+ ** the BtCursor object is technical invalid when bNeedUnref>0. This
+ ** routine must invoke releasePageNotNull() on apPage[] entries that
+ ** are not reused prior to existing this function, in order to bring
+ ** the cursor back into a valid state.
+ */
+ bNeedUnref = pCur->iPage;
+ pCur->apPage[bNeedUnref] = pCur->pPage;
+ pCur->iPage = 0;
+ pCur->pPage = pCur->apPage[0];
+ pCur->ix = 0;
+ pCur->info.nSize = 0;
+ pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl);
+ }else{
+ bNeedUnref = 0;
+ rc = moveToRoot(pCur);
+ if( rc ){
+ if( rc==SQLITE_EMPTY ){
+ assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
+ *pRes = -1;
+ return SQLITE_OK;
+ }
+ return rc;
}
- return rc;
}
bypass_moveto_root:
}else{
chldPg = get4byte(findCell(pPage, lwr));
}
- pCur->ix = (u16)lwr;
- rc = moveToChild(pCur, chldPg);
- if( rc ) break;
+
+ /* The following is similar to an in-lined version of
+ **
+ ** pCur->ix = (u16)lwr;
+ ** rc = moveToChild(pCur, chldPg);
+ **
+ ** But with the additional feature that pCur->apPage[] entries
+ ** that have had their Unref() calls deferred might be reused.
+ ** Reusing an apPage[] entry bypasses a lot of look-up and
+ ** initialization logic and hence saves many CPU cycles.
+ */
+ pCur->info.nSize = 0;
+ pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
+ if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){
+ assert( bNeedUnref==0 );
+ return SQLITE_CORRUPT_BKPT;
+ }
+ pCur->aiIdx[pCur->iPage] = (u16)lwr;
+ pCur->apPage[pCur->iPage] = pCur->pPage;
+ pCur->ix = 0;
+ pCur->iPage++;
+ if( bNeedUnref && pCur->apPage[pCur->iPage]->pgno==chldPg ){
+ pCur->pPage = pCur->apPage[pCur->iPage];
+ }else{
+ if( bNeedUnref ){
+ while( bNeedUnref>=pCur->iPage ){
+ releasePageNotNull(pCur->apPage[bNeedUnref--]);
+ }
+ bNeedUnref = 0;
+ }
+ rc = getAndInitPage(pCur->pBt, chldPg, &pCur->pPage, pCur,
+ pCur->curPagerFlags);
+ if( rc ) break;
+ }
}
moveto_index_finish:
pCur->info.nSize = 0;
+ if( bNeedUnref ){
+ while( bNeedUnref>pCur->iPage ){
+ releasePageNotNull(pCur->apPage[bNeedUnref--]);
+ }
+ }
assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
return rc;
}