/ Check-in [03dceaea]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Enhance sqlite3PcacheTruncate() to run faster in the common case where the cutoff is just a few pages less than the page number highwater mark.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | branch-3.14
Files: files | file ages | folders
SHA1: 03dceaea15aa357097a4615ef6044be36d505044
User & Date: drh 2016-08-11 13:03:51
Context
2016-08-11
13:08
Increase the version number to 3.14.1. check-in: 34aed3a3 user: drh tags: branch-3.14
13:03
Enhance sqlite3PcacheTruncate() to run faster in the common case where the cutoff is just a few pages less than the page number highwater mark. check-in: 03dceaea user: drh tags: branch-3.14
2016-08-10
15:02
Tweaks to pcache1TruncateUnsafe() to make it slightly smaller and faster and easier to test. check-in: 059f4e2e user: drh tags: trunk
11:50
Fix pcache1TruncateUnsafe() run faster for the case where iLimit is very close to iMaxKey. check-in: b07a26df user: drh tags: trunk
2016-08-08
13:40
Version 3.14 check-in: d5e98057 user: drh tags: trunk, release, version-3.14.0
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/pcache1.c.

   628    628   **
   629    629   ** The PCache mutex must be held when this function is called.
   630    630   */
   631    631   static void pcache1TruncateUnsafe(
   632    632     PCache1 *pCache,             /* The cache to truncate */
   633    633     unsigned int iLimit          /* Drop pages with this pgno or larger */
   634    634   ){
   635         -  TESTONLY( unsigned int nPage = 0; )  /* To assert pCache->nPage is correct */
   636         -  unsigned int h;
          635  +  TESTONLY( int nPage = 0; )  /* To assert pCache->nPage is correct */
          636  +  unsigned int h, iStop;
   637    637     assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
   638         -  for(h=0; h<pCache->nHash; h++){
   639         -    PgHdr1 **pp = &pCache->apHash[h]; 
          638  +  assert( pCache->iMaxKey >= iLimit );
          639  +  assert( pCache->nHash > 0 );
          640  +  if( pCache->iMaxKey - iLimit < pCache->nHash ){
          641  +    /* If we are just shaving the last few pages off the end of the
          642  +    ** cache, then there is no point in scanning the entire hash table.
          643  +    ** Only scan those hash slots that might contain pages that need to
          644  +    ** be removed. */
          645  +    h = iLimit % pCache->nHash;
          646  +    iStop = pCache->iMaxKey % pCache->nHash;
          647  +    TESTONLY( nPage = -10; )  /* Disable the pCache->nPage validity check */
          648  +  }else{
          649  +    /* This is the general case where many pages are being removed.
          650  +    ** It is necessary to scan the entire hash table */
          651  +    h = pCache->nHash/2;
          652  +    iStop = h - 1;
          653  +  }
          654  +  for(;;){
          655  +    PgHdr1 **pp;
   640    656       PgHdr1 *pPage;
          657  +    assert( h<pCache->nHash );
          658  +    pp = &pCache->apHash[h]; 
   641    659       while( (pPage = *pp)!=0 ){
   642    660         if( pPage->iKey>=iLimit ){
   643    661           pCache->nPage--;
   644    662           *pp = pPage->pNext;
   645    663           if( !pPage->isPinned ) pcache1PinPage(pPage);
   646    664           pcache1FreePage(pPage);
   647    665         }else{
   648    666           pp = &pPage->pNext;
   649         -        TESTONLY( nPage++; )
          667  +        TESTONLY( if( nPage>=0 ) nPage++; )
   650    668         }
   651    669       }
          670  +    if( h==iStop ) break;
          671  +    h = (h+1) % pCache->nHash;
   652    672     }
   653         -  assert( pCache->nPage==nPage );
          673  +  assert( nPage<0 || pCache->nPage==(unsigned)nPage );
   654    674   }
   655    675   
   656    676   /******************************************************************************/
   657    677   /******** sqlite3_pcache Methods **********************************************/
   658    678   
   659    679   /*
   660    680   ** Implementation of the sqlite3_pcache.xInit method.
................................................................................
  1123   1143   ** Destroy a cache allocated using pcache1Create().
  1124   1144   */
  1125   1145   static void pcache1Destroy(sqlite3_pcache *p){
  1126   1146     PCache1 *pCache = (PCache1 *)p;
  1127   1147     PGroup *pGroup = pCache->pGroup;
  1128   1148     assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) );
  1129   1149     pcache1EnterMutex(pGroup);
  1130         -  pcache1TruncateUnsafe(pCache, 0);
         1150  +  if( pCache->nPage ) pcache1TruncateUnsafe(pCache, 0);
  1131   1151     assert( pGroup->nMaxPage >= pCache->nMax );
  1132   1152     pGroup->nMaxPage -= pCache->nMax;
  1133   1153     assert( pGroup->nMinPage >= pCache->nMin );
  1134   1154     pGroup->nMinPage -= pCache->nMin;
  1135   1155     pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
  1136   1156     pcache1EnforceMaxPage(pCache);
  1137   1157     pcache1LeaveMutex(pGroup);