/ Check-in [9ab53605]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Try to make pcache1TruncateUnsafe() run faster for the case where iLimit is very close to iMaxKey.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | debug
Files: files | file ages | folders
SHA1:9ab53605d562a926c5620cba9dc96a3b812a432f
User & Date: drh 2016-08-10 03:35:50
Context
2016-08-10
11:50
Fix pcache1TruncateUnsafe() run faster for the case where iLimit is very close to iMaxKey. check-in: b07a26df user: drh tags: trunk
03:35
Try to make pcache1TruncateUnsafe() run faster for the case where iLimit is very close to iMaxKey. Leaf check-in: 9ab53605 user: drh tags: debug
02:54
Remove all timers and other debugging logs except for the one timer on pcache1TruncateUnsafe(). check-in: 5980e625 user: drh tags: debug
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/pcache1.c.

   494    494   **
   495    495   ** The PCache mutex must be held when this function is called.
   496    496   */
   497    497   static void pcache1TruncateUnsafe(
   498    498     PCache1 *pCache,             /* The cache to truncate */
   499    499     unsigned int iLimit          /* Drop pages with this pgno or larger */
   500    500   ){
   501         -  TESTONLY( unsigned int nPage = 0; )  /* To assert pCache->nPage is correct */
   502         -  unsigned int h;
          501  +  TESTONLY( int nPage = 0; )  /* To assert pCache->nPage is correct */
          502  +  unsigned int h, iStop;
   503    503     START_DEBUG_TIMER;
   504    504     int nFree = 0;
   505    505     assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
   506         -  for(h=0; h<pCache->nHash; h++){
   507         -    PgHdr1 **pp = &pCache->apHash[h]; 
          506  +  assert( pCache->iMaxKey >= iLimit );
          507  +  assert( pCache->nHash > 0 );
          508  +  if( pCache->iMaxKey - iLimit < pCache->nHash/2 ){
          509  +    /* If we are just shaving the last few pages off the end of the
          510  +    ** cache, then there is no point in scanning the entire hash table.
          511  +    ** Only scan those hash slots that might contain pages that need to
          512  +    ** be removed. */
          513  +    iStop = iLimit % pCache->nHash;
          514  +    h = pCache->iMaxKey % pCache->nHash;
          515  +    TESTONLY( nPage = -10; )  /* Disable the pCache->nPage validity check */
          516  +  }else{
          517  +    /* This is the general case where many pages are being removed.
          518  +    ** It is necessary to scan the entire hash table */
          519  +    iStop = 0;
          520  +    h = pCache->nHash - 1;
          521  +  }
          522  +  for(;;){
          523  +    PgHdr1 **pp;
   508    524       PgHdr1 *pPage;
          525  +    assert( h<pCache->nHash );
          526  +    pp = &pCache->apHash[h]; 
   509    527       while( (pPage = *pp)!=0 ){
   510    528         if( pPage->iKey>=iLimit ){
   511    529           pCache->nPage--;
   512    530           nFree++;
   513    531           *pp = pPage->pNext;
   514    532           if( !pPage->isPinned ) pcache1PinPage(pPage);
   515    533           pcache1FreePage(pPage);
   516    534         }else{
   517    535           pp = &pPage->pNext;
   518         -        TESTONLY( nPage++; )
          536  +        TESTONLY( if( nPage>=0 ) nPage++; )
   519    537         }
   520    538       }
          539  +    if( h==iStop ) break;
          540  +    h = h ? h-1 : pCache->nHash - 1;
   521    541     }
   522         -  assert( pCache->nPage==nPage );
          542  +  assert( nPage<0 || pCache->nPage==(unsigned)nPage );
   523    543     END_DEBUG_TIMER( DEBUG_TIMER_BIG_TIMEOUT ){
   524    544       sqlite3_log(SQLITE_NOTICE, 
   525    545          "slow pcache1TruncateUnsafe() %lld "
   526    546          " nFree=%d nHash=%d nPage=%d iLimit=%d iMaxKey=%d",
   527    547          iDebugTimer,
   528    548          nFree, pCache->nHash, pCache->nPage, iLimit, pCache->iMaxKey);
   529    549     }
................................................................................
   951    971   ** Destroy a cache allocated using pcache1Create().
   952    972   */
   953    973   static void pcache1Destroy(sqlite3_pcache *p){
   954    974     PCache1 *pCache = (PCache1 *)p;
   955    975     PGroup *pGroup = pCache->pGroup;
   956    976     assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) );
   957    977     pcache1EnterMutex(pGroup);
   958         -  pcache1TruncateUnsafe(pCache, 0);
          978  +  if( pCache->nPage ) pcache1TruncateUnsafe(pCache, 0);
   959    979     assert( pGroup->nMaxPage >= pCache->nMax );
   960    980     pGroup->nMaxPage -= pCache->nMax;
   961    981     assert( pGroup->nMinPage >= pCache->nMin );
   962    982     pGroup->nMinPage -= pCache->nMin;
   963    983     pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
   964    984     pcache1EnforceMaxPage(pGroup);
   965    985     pcache1LeaveMutex(pGroup);