/ Check-in [ffd437da]
Login

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

Overview
Comment:Small performance optimization in pcache1.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: ffd437da9541f8a2792e3e07c0a43f388f856fdc211fe42755eb51bfa5995d9f
User & Date: drh 2017-08-30 04:44:59
Context
2017-08-30
13:21
Remove unnecessary "__declspec(dllexport)" qualifiers from generated file shell.c. check-in: bcc20be5 user: dan tags: trunk
04:44
Small performance optimization in pcache1. check-in: ffd437da user: drh tags: trunk
2017-08-29
20:21
Faster memory allocation from lookaside by not trying to keep track of the number of outstanding allocations, and rather computing that value only when requested. check-in: a06263f1 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/pcache1.c.

   133    133   ** SQLITE_MUTEX_STATIC_LRU.
   134    134   */
   135    135   struct PGroup {
   136    136     sqlite3_mutex *mutex;          /* MUTEX_STATIC_LRU or NULL */
   137    137     unsigned int nMaxPage;         /* Sum of nMax for purgeable caches */
   138    138     unsigned int nMinPage;         /* Sum of nMin for purgeable caches */
   139    139     unsigned int mxPinned;         /* nMaxpage + 10 - nMinPage */
   140         -  unsigned int nCurrentPage;     /* Number of purgeable pages allocated */
          140  +  unsigned int nPurgeable;       /* Number of purgeable pages allocated */
   141    141     PgHdr1 lru;                    /* The beginning and end of the LRU list */
   142    142   };
   143    143   
   144    144   /* Each page cache is an instance of the following object.  Every
   145    145   ** open database file (including each in-memory database and each
   146    146   ** temporary or transient database) has a single page cache which
   147    147   ** is an instance of this object.
   148    148   **
   149    149   ** Pointers to structures of this type are cast and returned as 
   150    150   ** opaque sqlite3_pcache* handles.
   151    151   */
   152    152   struct PCache1 {
   153    153     /* Cache configuration parameters. Page size (szPage) and the purgeable
   154         -  ** flag (bPurgeable) are set when the cache is created. nMax may be 
          154  +  ** flag (bPurgeable) and the pnPurgeable pointer are all set when the
          155  +  ** cache is created and are never changed thereafter. nMax may be 
   155    156     ** modified at any time by a call to the pcache1Cachesize() method.
   156    157     ** The PGroup mutex must be held when accessing nMax.
   157    158     */
   158    159     PGroup *pGroup;                     /* PGroup this cache belongs to */
          160  +  unsigned int *pnPurgeable;          /* Pointer to pGroup->nPurgeable */
   159    161     int szPage;                         /* Size of database content section */
   160    162     int szExtra;                        /* sizeof(MemPage)+sizeof(PgHdr) */
   161    163     int szAlloc;                        /* Total size of one pcache line */
   162    164     int bPurgeable;                     /* True if cache is purgeable */
   163    165     unsigned int nMin;                  /* Minimum number of pages reserved */
   164    166     unsigned int nMax;                  /* Configured "cache_size" value */
   165    167     unsigned int n90pct;                /* nMax*9/10 */
................................................................................
   439    441   #endif
   440    442       if( pPg==0 ) return 0;
   441    443       p->page.pBuf = pPg;
   442    444       p->page.pExtra = &p[1];
   443    445       p->isBulkLocal = 0;
   444    446       p->isAnchor = 0;
   445    447     }
   446         -  if( pCache->bPurgeable ){
   447         -    pCache->pGroup->nCurrentPage++;
   448         -  }
          448  +  (*pCache->pnPurgeable)++;
   449    449     return p;
   450    450   }
   451    451   
   452    452   /*
   453    453   ** Free a page object allocated by pcache1AllocPage().
   454    454   */
   455    455   static void pcache1FreePage(PgHdr1 *p){
................................................................................
   462    462       pCache->pFree = p;
   463    463     }else{
   464    464       pcache1Free(p->page.pBuf);
   465    465   #ifdef SQLITE_PCACHE_SEPARATE_HEADER
   466    466       sqlite3_free(p);
   467    467   #endif
   468    468     }
   469         -  if( pCache->bPurgeable ){
   470         -    pCache->pGroup->nCurrentPage--;
   471         -  }
          469  +  (*pCache->pnPurgeable)--;
   472    470   }
   473    471   
   474    472   /*
   475    473   ** Malloc function used by SQLite to obtain space from the buffer configured
   476    474   ** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer
   477    475   ** exists, this function falls back to sqlite3Malloc().
   478    476   */
................................................................................
   604    602   ** If there are currently more than nMaxPage pages allocated, try
   605    603   ** to recycle pages to reduce the number allocated to nMaxPage.
   606    604   */
   607    605   static void pcache1EnforceMaxPage(PCache1 *pCache){
   608    606     PGroup *pGroup = pCache->pGroup;
   609    607     PgHdr1 *p;
   610    608     assert( sqlite3_mutex_held(pGroup->mutex) );
   611         -  while( pGroup->nCurrentPage>pGroup->nMaxPage
          609  +  while( pGroup->nPurgeable>pGroup->nMaxPage
   612    610         && (p=pGroup->lru.pLruPrev)->isAnchor==0
   613    611     ){
   614    612       assert( p->pCache->pGroup==pGroup );
   615    613       assert( PAGE_IS_UNPINNED(p) );
   616    614       pcache1PinPage(p);
   617    615       pcache1RemoveFromHash(p, 1);
   618    616     }
................................................................................
   775    773       pCache->bPurgeable = (bPurgeable ? 1 : 0);
   776    774       pcache1EnterMutex(pGroup);
   777    775       pcache1ResizeHash(pCache);
   778    776       if( bPurgeable ){
   779    777         pCache->nMin = 10;
   780    778         pGroup->nMinPage += pCache->nMin;
   781    779         pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
          780  +      pCache->pnPurgeable = &pGroup->nPurgeable;
          781  +    }else{
          782  +      static unsigned int dummyCurrentPage;
          783  +      pCache->pnPurgeable = &dummyCurrentPage;
   782    784       }
   783    785       pcache1LeaveMutex(pGroup);
   784    786       if( pCache->nHash==0 ){
   785    787         pcache1Destroy((sqlite3_pcache*)pCache);
   786    788         pCache = 0;
   787    789       }
   788    790     }
................................................................................
   884    886       pcache1RemoveFromHash(pPage, 0);
   885    887       pcache1PinPage(pPage);
   886    888       pOther = pPage->pCache;
   887    889       if( pOther->szAlloc != pCache->szAlloc ){
   888    890         pcache1FreePage(pPage);
   889    891         pPage = 0;
   890    892       }else{
   891         -      pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable);
          893  +      pGroup->nPurgeable -= (pOther->bPurgeable - pCache->bPurgeable);
   892    894       }
   893    895     }
   894    896   
   895    897     /* Step 5. If a usable page buffer has still not been found, 
   896    898     ** attempt to allocate a new one. 
   897    899     */
   898    900     if( !pPage ){
................................................................................
  1065   1067   
  1066   1068     /* It is an error to call this function if the page is already 
  1067   1069     ** part of the PGroup LRU list.
  1068   1070     */
  1069   1071     assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
  1070   1072     assert( PAGE_IS_PINNED(pPage) );
  1071   1073   
  1072         -  if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){
         1074  +  if( reuseUnlikely || pGroup->nPurgeable>pGroup->nMaxPage ){
  1073   1075       pcache1RemoveFromHash(pPage, 1);
  1074   1076     }else{
  1075   1077       /* Add the page to the PGroup LRU list. */
  1076   1078       PgHdr1 **ppFirst = &pGroup->lru.pLruNext;
  1077   1079       pPage->pLruPrev = &pGroup->lru;
  1078   1080       (pPage->pLruNext = *ppFirst)->pLruPrev = pPage;
  1079   1081       *ppFirst = pPage;
................................................................................
  1244   1246   ){
  1245   1247     PgHdr1 *p;
  1246   1248     int nRecyclable = 0;
  1247   1249     for(p=pcache1.grp.lru.pLruNext; p && !p->isAnchor; p=p->pLruNext){
  1248   1250       assert( PAGE_IS_UNPINNED(p) );
  1249   1251       nRecyclable++;
  1250   1252     }
  1251         -  *pnCurrent = pcache1.grp.nCurrentPage;
         1253  +  *pnCurrent = pcache1.grp.nPurgeable;
  1252   1254     *pnMax = (int)pcache1.grp.nMaxPage;
  1253   1255     *pnMin = (int)pcache1.grp.nMinPage;
  1254   1256     *pnRecyclable = nRecyclable;
  1255   1257   }
  1256   1258   #endif