/ Check-in [5348ffc3]
Login

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

Overview
Comment:Enhance the pcache1 page cache so that it tries to allocate a block of SQLITE_DEFAULT_PCACHE_INITSZ pages from malloc() on startup, and uses those preallocated pages when possible rather than going to malloc() for each individual page. About a 5% performance increase for some workloads.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5348ffc3fda5168c1e9e14aa88b0c6aedbda7c94
User & Date: drh 2015-07-08 16:22:42
Context
2015-07-08
17:59
Fix two problems that could cause fts3 auxiliary functions to occasionally misbehave if used with match expressions that contain both OR and NEAR. check-in: 372c1db2 user: dan tags: trunk
16:22
Enhance the pcache1 page cache so that it tries to allocate a block of SQLITE_DEFAULT_PCACHE_INITSZ pages from malloc() on startup, and uses those preallocated pages when possible rather than going to malloc() for each individual page. About a 5% performance increase for some workloads. check-in: 5348ffc3 user: drh tags: trunk
14:13
Comment fix. No changes to code. Closed-Leaf check-in: c1e2ed0e user: drh tags: pcache-bulk-local
12:25
Early detection of file corruption in a debugging routine, before the invalid data can cause problems. check-in: b27a47fe user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

  9115   9115       */
  9116   9116       i = get2byte(&data[hdr+1]);
  9117   9117       while( i>0 ){
  9118   9118         int size, j;
  9119   9119         assert( (u32)i<=usableSize-4 );     /* Enforced by btreeInitPage() */
  9120   9120         size = get2byte(&data[i+2]);
  9121   9121         assert( (u32)(i+size)<=usableSize );  /* Enforced by btreeInitPage() */
  9122         -      btreeHeapInsert(heap, (i<<16)|(i+size-1));
         9122  +      btreeHeapInsert(heap, (((u32)i)<<16)|(i+size-1));
  9123   9123         /* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a
  9124   9124         ** big-endian integer which is the offset in the b-tree page of the next
  9125   9125         ** freeblock in the chain, or zero if the freeblock is the last on the
  9126   9126         ** chain. */
  9127   9127         j = get2byte(&data[i]);
  9128   9128         /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of
  9129   9129         ** increasing offset. */

Changes to src/global.c.

   182    182      SQLITE_DEFAULT_MMAP_SIZE,  /* szMmap */
   183    183      SQLITE_MAX_MMAP_SIZE,      /* mxMmap */
   184    184      (void*)0,                  /* pScratch */
   185    185      0,                         /* szScratch */
   186    186      0,                         /* nScratch */
   187    187      (void*)0,                  /* pPage */
   188    188      0,                         /* szPage */
   189         -   0,                         /* nPage */
          189  +   SQLITE_DEFAULT_PCACHE_INITSZ, /* nPage */
   190    190      0,                         /* mxParserStack */
   191    191      0,                         /* sharedCacheEnabled */
   192    192      SQLITE_SORTER_PMASZ,       /* szPma */
   193    193      /* All the rest should always be initialized to zero */
   194    194      0,                         /* isInit */
   195    195      0,                         /* inProgress */
   196    196      0,                         /* isMutexInit */

Changes to src/pcache1.c.

    37     37   ** runtime using sqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &size).  The
    38     38   ** sizes of the extensions sum to 272 bytes on x64 for 3.8.10, but this
    39     39   ** size can vary according to architecture, compile-time options, and
    40     40   ** SQLite library version number.
    41     41   **
    42     42   ** If SQLITE_PCACHE_SEPARATE_HEADER is defined, then the extension is obtained
    43     43   ** using a separate memory allocation from the database page content.  This
    44         -** seeks to overcome the "clownfoot" problem of allocating a few bytes more
           44  +** seeks to overcome the "clownshoe" problem (also called "internal
           45  +** fragmentation" in academic literature) of allocating a few bytes more
    45     46   ** than a power of two with the memory allocator rounding up to the next
    46     47   ** power of two, and leaving the rounded-up space unused.
    47     48   **
    48     49   ** This module tracks pointers to PgHdr1 objects.  Only pcache.c communicates
    49     50   ** with this module.  Information is passed back and forth as PgHdr1 pointers.
    50     51   **
    51     52   ** The pcache.c and pager.c modules deal pointers to PgHdr objects.
    52     53   ** The btree.c module deals with pointers to MemPage objects.
           54  +**
           55  +** SOURCE OF PAGE CACHE MEMORY:
           56  +**
           57  +** Memory for a page might come from any of three sources:
           58  +**
           59  +**    (1)  The general-purpose memory allocator - sqlite3Malloc()
           60  +**    (2)  Global page-cache memory provided using sqlite3_config() with
           61  +**         SQLITE_CONFIG_PAGECACHE.
           62  +**    (3)  PCache-local bulk allocation.
           63  +**
           64  +** The third case is a chunk of heap memory (defaulting to 100 pages worth)
           65  +** that is allocated when the page cache is created.  The size of the local
           66  +** bulk allocation can be adjusted using 
           67  +**
           68  +**     sqlite3_config(SQLITE_CONFIG_PCACHE, 0, 0, N).
           69  +**
           70  +** If N is positive, then N pages worth of memory are allocated using a single
           71  +** sqlite3Malloc() call and that memory is used for the first N pages allocated.
           72  +** Or if N is negative, then -1024*N bytes of memory are allocated and used
           73  +** for as many pages as can be accomodated.
           74  +**
           75  +** Only one of (2) or (3) can be used.  Once the memory available to (2) or
           76  +** (3) is exhausted, subsequent allocations fail over to the general-purpose
           77  +** memory allocator (1).
           78  +**
           79  +** Earlier versions of SQLite used only methods (1) and (2).  But experiments
           80  +** show that method (3) with N==100 provides about a 5% performance boost for
           81  +** common workloads.
    53     82   */
    54         -
    55     83   #include "sqliteInt.h"
    56     84   
    57     85   typedef struct PCache1 PCache1;
    58     86   typedef struct PgHdr1 PgHdr1;
    59     87   typedef struct PgFreeslot PgFreeslot;
    60     88   typedef struct PGroup PGroup;
    61     89   
................................................................................
   101    129   struct PCache1 {
   102    130     /* Cache configuration parameters. Page size (szPage) and the purgeable
   103    131     ** flag (bPurgeable) are set when the cache is created. nMax may be 
   104    132     ** modified at any time by a call to the pcache1Cachesize() method.
   105    133     ** The PGroup mutex must be held when accessing nMax.
   106    134     */
   107    135     PGroup *pGroup;                     /* PGroup this cache belongs to */
   108         -  int szPage;                         /* Size of allocated pages in bytes */
   109         -  int szExtra;                        /* Size of extra space in bytes */
          136  +  int szPage;                         /* Size of database content section */
          137  +  int szExtra;                        /* sizeof(MemPage)+sizeof(PgHdr) */
          138  +  int szAlloc;                        /* Total size of one pcache line */
   110    139     int bPurgeable;                     /* True if cache is purgeable */
   111    140     unsigned int nMin;                  /* Minimum number of pages reserved */
   112    141     unsigned int nMax;                  /* Configured "cache_size" value */
   113    142     unsigned int n90pct;                /* nMax*9/10 */
   114    143     unsigned int iMaxKey;               /* Largest key seen since xTruncate() */
   115    144   
   116    145     /* Hash table of all pages. The following variables may only be accessed
   117    146     ** when the accessor is holding the PGroup mutex.
   118    147     */
   119    148     unsigned int nRecyclable;           /* Number of pages in the LRU list */
   120    149     unsigned int nPage;                 /* Total number of pages in apHash */
   121    150     unsigned int nHash;                 /* Number of slots in apHash[] */
   122    151     PgHdr1 **apHash;                    /* Hash table for fast lookup by key */
          152  +  PgHdr1 *pFree;                      /* List of unused pcache-local pages */
          153  +  void *pBulk;                        /* Bulk memory used by pcache-local */
   123    154   };
   124    155   
   125    156   /*
   126    157   ** Each cache entry is represented by an instance of the following 
   127    158   ** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
   128    159   ** PgHdr1.pCache->szPage bytes is allocated directly before this structure 
   129    160   ** in memory.
   130    161   */
   131    162   struct PgHdr1 {
   132    163     sqlite3_pcache_page page;
   133    164     unsigned int iKey;             /* Key value (page number) */
   134    165     u8 isPinned;                   /* Page in use, not on the LRU list */
          166  +  u8 isBulkLocal;                /* This page from bulk local storage */
   135    167     PgHdr1 *pNext;                 /* Next in hash table chain */
   136    168     PCache1 *pCache;               /* Cache that currently owns this page */
   137    169     PgHdr1 *pLruNext;              /* Next in LRU list of unpinned pages */
   138    170     PgHdr1 *pLruPrev;              /* Previous in LRU list of unpinned pages */
   139    171   };
   140    172   
   141    173   /*
   142         -** Free slots in the allocator used to divide up the buffer provided using
   143         -** the SQLITE_CONFIG_PAGECACHE mechanism.
          174  +** Free slots in the allocator used to divide up the global page cache
          175  +** buffer provided using the SQLITE_CONFIG_PAGECACHE mechanism.
   144    176   */
   145    177   struct PgFreeslot {
   146    178     PgFreeslot *pNext;  /* Next free slot */
   147    179   };
   148    180   
   149    181   /*
   150    182   ** Global data used by this cache.
................................................................................
   154    186   
   155    187     /* Variables related to SQLITE_CONFIG_PAGECACHE settings.  The
   156    188     ** szSlot, nSlot, pStart, pEnd, nReserve, and isInit values are all
   157    189     ** fixed at sqlite3_initialize() time and do not require mutex protection.
   158    190     ** The nFreeSlot and pFree values do require mutex protection.
   159    191     */
   160    192     int isInit;                    /* True if initialized */
          193  +  int separateCache;             /* Use a new PGroup for each PCache */
   161    194     int szSlot;                    /* Size of each free slot */
   162    195     int nSlot;                     /* The number of pcache slots */
   163    196     int nReserve;                  /* Try to keep nFreeSlot above this */
   164         -  void *pStart, *pEnd;           /* Bounds of pagecache malloc range */
          197  +  void *pStart, *pEnd;           /* Bounds of global page cache memory */
   165    198     /* Above requires no mutex.  Use mutex below for variable that follow. */
   166    199     sqlite3_mutex *mutex;          /* Mutex for accessing the following: */
   167    200     PgFreeslot *pFree;             /* Free page blocks */
   168    201     int nFreeSlot;                 /* Number of unused pcache slots */
   169    202     /* The following value requires a mutex to change.  We skip the mutex on
   170    203     ** reading because (1) most platforms read a 32-bit integer atomically and
   171    204     ** (2) even if an incorrect value is read, no great harm is done since this
................................................................................
   204    237   **
   205    238   ** This routine is called from sqlite3_initialize() and so it is guaranteed
   206    239   ** to be serialized already.  There is no need for further mutexing.
   207    240   */
   208    241   void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
   209    242     if( pcache1.isInit ){
   210    243       PgFreeslot *p;
          244  +    if( pBuf==0 ) sz = n = 0;
   211    245       sz = ROUNDDOWN8(sz);
   212    246       pcache1.szSlot = sz;
   213    247       pcache1.nSlot = pcache1.nFreeSlot = n;
   214    248       pcache1.nReserve = n>90 ? 10 : (n/10 + 1);
   215    249       pcache1.pStart = pBuf;
   216    250       pcache1.pFree = 0;
   217    251       pcache1.bUnderPressure = 0;
................................................................................
   268    302     }
   269    303     return p;
   270    304   }
   271    305   
   272    306   /*
   273    307   ** Free an allocated buffer obtained from pcache1Alloc().
   274    308   */
   275         -static int pcache1Free(void *p){
          309  +static void pcache1Free(void *p){
   276    310     int nFreed = 0;
   277         -  if( p==0 ) return 0;
          311  +  if( p==0 ) return;
   278    312     if( p>=pcache1.pStart && p<pcache1.pEnd ){
   279    313       PgFreeslot *pSlot;
   280    314       sqlite3_mutex_enter(pcache1.mutex);
   281    315       sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1);
   282    316       pSlot = (PgFreeslot*)p;
   283    317       pSlot->pNext = pcache1.pFree;
   284    318       pcache1.pFree = pSlot;
................................................................................
   285    319       pcache1.nFreeSlot++;
   286    320       pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
   287    321       assert( pcache1.nFreeSlot<=pcache1.nSlot );
   288    322       sqlite3_mutex_leave(pcache1.mutex);
   289    323     }else{
   290    324       assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
   291    325       sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
   292         -    nFreed = sqlite3MallocSize(p);
   293    326   #ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
          327  +    nFreed = sqlite3MallocSize(p);
   294    328       sqlite3_mutex_enter(pcache1.mutex);
   295    329       sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed);
   296    330       sqlite3_mutex_leave(pcache1.mutex);
   297    331   #endif
   298    332       sqlite3_free(p);
   299    333     }
   300         -  return nFreed;
   301    334   }
   302    335   
   303    336   #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   304    337   /*
   305    338   ** Return the size of a pcache allocation
   306    339   */
   307    340   static int pcache1MemSize(void *p){
................................................................................
   321    354   /*
   322    355   ** Allocate a new page object initially associated with cache pCache.
   323    356   */
   324    357   static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
   325    358     PgHdr1 *p = 0;
   326    359     void *pPg;
   327    360   
   328         -  /* The group mutex must be released before pcache1Alloc() is called. This
   329         -  ** is because it may call sqlite3_release_memory(), which assumes that 
   330         -  ** this mutex is not held. */
   331    361     assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
   332         -  pcache1LeaveMutex(pCache->pGroup);
          362  +  if( pCache->pFree ){
          363  +    p = pCache->pFree;
          364  +    pCache->pFree = p->pNext;
          365  +    p->pNext = 0;
          366  +  }else{
          367  +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
          368  +    /* The group mutex must be released before pcache1Alloc() is called. This
          369  +    ** is because it might call sqlite3_release_memory(), which assumes that 
          370  +    ** this mutex is not held. */
          371  +    assert( pcache1.separateCache==0 );
          372  +    assert( pCache->pGroup==&pcache1.grp );
          373  +    pcache1LeaveMutex(pCache->pGroup);
          374  +#endif
   333    375   #ifdef SQLITE_PCACHE_SEPARATE_HEADER
   334         -  pPg = pcache1Alloc(pCache->szPage);
   335         -  p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
   336         -  if( !pPg || !p ){
   337         -    pcache1Free(pPg);
   338         -    sqlite3_free(p);
   339         -    pPg = 0;
   340         -  }
          376  +    pPg = pcache1Alloc(pCache->szPage);
          377  +    p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
          378  +    if( !pPg || !p ){
          379  +      pcache1Free(pPg);
          380  +      sqlite3_free(p);
          381  +      pPg = 0;
          382  +    }
   341    383   #else
   342         -  pPg = pcache1Alloc(ROUND8(sizeof(PgHdr1)) + pCache->szPage + pCache->szExtra);
   343         -  p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
          384  +    pPg = pcache1Alloc(pCache->szAlloc);
          385  +    p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
          386  +#endif
          387  +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
          388  +    pcache1EnterMutex(pCache->pGroup);
   344    389   #endif
   345         -  pcache1EnterMutex(pCache->pGroup);
   346         -
   347         -  if( pPg ){
          390  +    if( pPg==0 ) return 0;
   348    391       p->page.pBuf = pPg;
   349    392       p->page.pExtra = &p[1];
   350         -    if( pCache->bPurgeable ){
   351         -      pCache->pGroup->nCurrentPage++;
   352         -    }
   353         -    return p;
          393  +    p->isBulkLocal = 0;
   354    394     }
   355         -  return 0;
          395  +  if( pCache->bPurgeable ){
          396  +    pCache->pGroup->nCurrentPage++;
          397  +  }
          398  +  return p;
   356    399   }
   357    400   
   358    401   /*
   359    402   ** Free a page object allocated by pcache1AllocPage().
   360         -**
   361         -** The pointer is allowed to be NULL, which is prudent.  But it turns out
   362         -** that the current implementation happens to never call this routine
   363         -** with a NULL pointer, so we mark the NULL test with ALWAYS().
   364    403   */
   365    404   static void pcache1FreePage(PgHdr1 *p){
   366         -  if( ALWAYS(p) ){
   367         -    PCache1 *pCache = p->pCache;
   368         -    assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
          405  +  PCache1 *pCache;
          406  +  assert( p!=0 );
          407  +  pCache = p->pCache;
          408  +  assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
          409  +  if( p->isBulkLocal ){
          410  +    p->pNext = pCache->pFree;
          411  +    pCache->pFree = p;
          412  +  }else{
   369    413       pcache1Free(p->page.pBuf);
   370    414   #ifdef SQLITE_PCACHE_SEPARATE_HEADER
   371    415       sqlite3_free(p);
   372    416   #endif
   373         -    if( pCache->bPurgeable ){
   374         -      pCache->pGroup->nCurrentPage--;
   375         -    }
          417  +  }
          418  +  if( pCache->bPurgeable ){
          419  +    pCache->pGroup->nCurrentPage--;
   376    420     }
   377    421   }
   378    422   
   379    423   /*
   380    424   ** Malloc function used by SQLite to obtain space from the buffer configured
   381    425   ** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer
   382    426   ** exists, this function falls back to sqlite3Malloc().
................................................................................
   568    612   /*
   569    613   ** Implementation of the sqlite3_pcache.xInit method.
   570    614   */
   571    615   static int pcache1Init(void *NotUsed){
   572    616     UNUSED_PARAMETER(NotUsed);
   573    617     assert( pcache1.isInit==0 );
   574    618     memset(&pcache1, 0, sizeof(pcache1));
          619  +
          620  +
          621  +  /*
          622  +  ** The pcache1.separateCache variable is true if each PCache has its own
          623  +  ** private PGroup (mode-1).  pcache1.separateCache is false if the single
          624  +  ** PGroup in pcache1.grp is used for all page caches (mode-2).
          625  +  **
          626  +  **   *  Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT
          627  +  **
          628  +  **   *  Use a unified cache in single-threaded applications that have
          629  +  **      configured a start-time buffer for use as page-cache memory using
          630  +  **      sqlite3_config(SQLITE_CONFIG_PAGECACHE, pBuf, sz, N) with non-NULL 
          631  +  **      pBuf argument.
          632  +  **
          633  +  **   *  Otherwise use separate caches (mode-1)
          634  +  */
          635  +#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT)
          636  +  pcache1.separateCache = 0;
          637  +#elif SQLITE_THREADSAFE
          638  +  pcache1.separateCache = sqlite3GlobalConfig.pPage==0
          639  +                          || sqlite3GlobalConfig.bCoreMutex>0;
          640  +#else
          641  +  pcache1.separateCache = sqlite3GlobalConfig.pPage==0;
          642  +#endif
          643  +
   575    644   #if SQLITE_THREADSAFE
   576    645     if( sqlite3GlobalConfig.bCoreMutex ){
   577    646       pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
   578    647       pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM);
   579    648     }
   580    649   #endif
   581    650     pcache1.grp.mxPinned = 10;
................................................................................
   603    672   ** Allocate a new cache.
   604    673   */
   605    674   static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
   606    675     PCache1 *pCache;      /* The newly created page cache */
   607    676     PGroup *pGroup;       /* The group the new page cache will belong to */
   608    677     int sz;               /* Bytes of memory required to allocate the new cache */
   609    678   
   610         -  /*
   611         -  ** The separateCache variable is true if each PCache has its own private
   612         -  ** PGroup.  In other words, separateCache is true for mode (1) where no
   613         -  ** mutexing is required.
   614         -  **
   615         -  **   *  Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT
   616         -  **
   617         -  **   *  Always use a unified cache in single-threaded applications
   618         -  **
   619         -  **   *  Otherwise (if multi-threaded and ENABLE_MEMORY_MANAGEMENT is off)
   620         -  **      use separate caches (mode-1)
   621         -  */
   622         -#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0
   623         -  const int separateCache = 0;
   624         -#else
   625         -  int separateCache = sqlite3GlobalConfig.bCoreMutex>0;
   626         -#endif
   627         -
   628    679     assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 );
   629    680     assert( szExtra < 300 );
   630    681   
   631         -  sz = sizeof(PCache1) + sizeof(PGroup)*separateCache;
          682  +  sz = sizeof(PCache1) + sizeof(PGroup)*pcache1.separateCache;
   632    683     pCache = (PCache1 *)sqlite3MallocZero(sz);
   633    684     if( pCache ){
   634         -    if( separateCache ){
          685  +    if( pcache1.separateCache ){
   635    686         pGroup = (PGroup*)&pCache[1];
   636    687         pGroup->mxPinned = 10;
   637    688       }else{
   638    689         pGroup = &pcache1.grp;
   639    690       }
   640    691       pCache->pGroup = pGroup;
   641    692       pCache->szPage = szPage;
   642    693       pCache->szExtra = szExtra;
          694  +    pCache->szAlloc = szPage + szExtra + ROUND8(sizeof(PgHdr1));
   643    695       pCache->bPurgeable = (bPurgeable ? 1 : 0);
   644    696       pcache1EnterMutex(pGroup);
   645    697       pcache1ResizeHash(pCache);
   646    698       if( bPurgeable ){
   647    699         pCache->nMin = 10;
   648    700         pGroup->nMinPage += pCache->nMin;
   649    701         pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
   650    702       }
   651    703       pcache1LeaveMutex(pGroup);
          704  +    /* Try to initialize the local bulk pagecache line allocation if using
          705  +    ** separate caches and if nPage!=0 */
          706  +    if( pcache1.separateCache
          707  +     && sqlite3GlobalConfig.nPage!=0
          708  +     && sqlite3GlobalConfig.pPage==0
          709  +    ){
          710  +      int szBulk;
          711  +      char *zBulk;
          712  +      sqlite3BeginBenignMalloc();
          713  +      if( sqlite3GlobalConfig.nPage>0 ){
          714  +        szBulk = pCache->szAlloc * sqlite3GlobalConfig.nPage;
          715  +      }else{
          716  +        szBulk = -1024*sqlite3GlobalConfig.nPage;
          717  +      }
          718  +      zBulk = pCache->pBulk = sqlite3Malloc( szBulk );
          719  +      sqlite3EndBenignMalloc();
          720  +      if( zBulk ){
          721  +        int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc;
          722  +        int i;
          723  +        for(i=0; i<nBulk; i++){
          724  +          PgHdr1 *pX = (PgHdr1*)&zBulk[szPage];
          725  +          pX->page.pBuf = zBulk;
          726  +          pX->page.pExtra = &pX[1];
          727  +          pX->isBulkLocal = 1;
          728  +          pX->pNext = pCache->pFree;
          729  +          pCache->pFree = pX;
          730  +          zBulk += pCache->szAlloc;
          731  +        }
          732  +      }
          733  +    }
   652    734       if( pCache->nHash==0 ){
   653    735         pcache1Destroy((sqlite3_pcache*)pCache);
   654    736         pCache = 0;
   655    737       }
   656    738     }
   657    739     return (sqlite3_pcache *)pCache;
   658    740   }
................................................................................
   738    820       return 0;
   739    821     }
   740    822   
   741    823     if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
   742    824     assert( pCache->nHash>0 && pCache->apHash );
   743    825   
   744    826     /* Step 4. Try to recycle a page. */
   745         -  if( pCache->bPurgeable && pGroup->pLruTail && (
   746         -         (pCache->nPage+1>=pCache->nMax)
   747         -      || pGroup->nCurrentPage>=pGroup->nMaxPage
   748         -      || pcache1UnderMemoryPressure(pCache)
   749         -  )){
          827  +  if( pCache->bPurgeable
          828  +   && pGroup->pLruTail
          829  +   && ((pCache->nPage+1>=pCache->nMax) || pcache1UnderMemoryPressure(pCache))
          830  +  ){
   750    831       PCache1 *pOther;
   751    832       pPage = pGroup->pLruTail;
   752    833       assert( pPage->isPinned==0 );
   753    834       pcache1RemoveFromHash(pPage, 0);
   754    835       pcache1PinPage(pPage);
   755    836       pOther = pPage->pCache;
   756         -
   757         -    /* We want to verify that szPage and szExtra are the same for pOther
   758         -    ** and pCache.  Assert that we can verify this by comparing sums. */
   759         -    assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 );
   760         -    assert( pCache->szExtra<512 );
   761         -    assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 );
   762         -    assert( pOther->szExtra<512 );
   763         -
   764         -    if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){
          837  +    if( pOther->szAlloc != pCache->szAlloc ){
   765    838         pcache1FreePage(pPage);
   766    839         pPage = 0;
   767    840       }else{
   768    841         pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable);
   769    842       }
   770    843     }
   771    844   
................................................................................
  1033   1106     assert( pGroup->nMaxPage >= pCache->nMax );
  1034   1107     pGroup->nMaxPage -= pCache->nMax;
  1035   1108     assert( pGroup->nMinPage >= pCache->nMin );
  1036   1109     pGroup->nMinPage -= pCache->nMin;
  1037   1110     pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
  1038   1111     pcache1EnforceMaxPage(pGroup);
  1039   1112     pcache1LeaveMutex(pGroup);
         1113  +  sqlite3_free(pCache->pBulk);
  1040   1114     sqlite3_free(pCache->apHash);
  1041   1115     sqlite3_free(pCache);
  1042   1116   }
  1043   1117   
  1044   1118   /*
  1045   1119   ** This function is called during initialization (sqlite3_initialize()) to
  1046   1120   ** install the default pluggable cache module, assuming the user has not
................................................................................
  1088   1162   ** been released, the function returns. The return value is the total number 
  1089   1163   ** of bytes of memory released.
  1090   1164   */
  1091   1165   int sqlite3PcacheReleaseMemory(int nReq){
  1092   1166     int nFree = 0;
  1093   1167     assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
  1094   1168     assert( sqlite3_mutex_notheld(pcache1.mutex) );
  1095         -  if( pcache1.pStart==0 ){
         1169  +  if( sqlite3GlobalConfig.nPage==0 ){
  1096   1170       PgHdr1 *p;
  1097   1171       pcache1EnterMutex(&pcache1.grp);
  1098   1172       while( (nReq<0 || nFree<nReq) && ((p=pcache1.grp.pLruTail)!=0) ){
  1099   1173         nFree += pcache1MemSize(p->page.pBuf);
  1100   1174   #ifdef SQLITE_PCACHE_SEPARATE_HEADER
  1101   1175         nFree += sqlite3MemSize(p);
  1102   1176   #endif

Changes to src/sqliteInt.h.

   505    505   # define SQLITE_DEFAULT_WORKER_THREADS 0
   506    506   #endif
   507    507   #if SQLITE_DEFAULT_WORKER_THREADS>SQLITE_MAX_WORKER_THREADS
   508    508   # undef SQLITE_MAX_WORKER_THREADS
   509    509   # define SQLITE_MAX_WORKER_THREADS SQLITE_DEFAULT_WORKER_THREADS
   510    510   #endif
   511    511   
          512  +/*
          513  +** The default initial allocation for the pagecache when using separate
          514  +** pagecaches for each database connection.  A positive number is the
          515  +** number of pages.  A negative number N translations means that a buffer
          516  +** of -1024*N bytes is allocated and used for as many pages as it will hold.
          517  +*/
          518  +#ifndef SQLITE_DEFAULT_PCACHE_INITSZ
          519  +# define SQLITE_DEFAULT_PCACHE_INITSZ 100
          520  +#endif
          521  +
   512    522   
   513    523   /*
   514    524   ** GCC does not define the offsetof() macro so we'll have to do it
   515    525   ** ourselves.
   516    526   */
   517    527   #ifndef offsetof
   518    528   #define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))

Changes to test/memdb.test.

   415    415       execsql {
   416    416         PRAGMA auto_vacuum = full;
   417    417         CREATE TABLE t1(a);
   418    418         INSERT INTO t1 VALUES(randstr(1000,1000));
   419    419         INSERT INTO t1 VALUES(randstr(1000,1000));
   420    420         INSERT INTO t1 VALUES(randstr(1000,1000));
   421    421       }
   422         -    set memused [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
   423         -    set pgovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 1]
          422  +    set before [db one {PRAGMA page_count}]
   424    423       execsql { DELETE FROM t1 }
   425         -    set memused2 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
   426         -    expr {($memused2 + 2048 < $memused) || $pgovfl==0}
          424  +    set after [db one {PRAGMA page_count}]
          425  +    expr {$before>$after}
   427    426     } {1}
   428    427   }
   429    428   
   430    429   } ;# ifcapable memorydb
   431    430   
   432    431   finish_test

Changes to test/memsubsys1.test.

    71     71   set xtra_size 290
    72     72   
    73     73   # Test 1:  Both PAGECACHE and SCRATCH are shut down.
    74     74   #
    75     75   db close
    76     76   sqlite3_shutdown
    77     77   sqlite3_config_lookaside 0 0
           78  +sqlite3_config_pagecache 0 0
    78     79   sqlite3_initialize
    79     80   reset_highwater_marks
    80     81   build_test_db memsubsys1-1 {PRAGMA page_size=1024}
    81     82   do_test memsubsys1-1.3 {
    82     83     set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
    83     84   } 0
    84     85   do_test memsubsys1-1.4 {
................................................................................
   111    112   
   112    113   # Test 3:  Activate PAGECACHE with 20 pages but use the wrong page size
   113    114   # so that PAGECACHE is not used.
   114    115   #
   115    116   db close
   116    117   sqlite3_shutdown
   117    118   sqlite3_config_pagecache [expr 512+$xtra_size] 20
          119  +sqlite3_config singlethread
   118    120   sqlite3_initialize
   119    121   reset_highwater_marks
   120    122   build_test_db memsubsys1-3.1 {PRAGMA page_size=1024}
   121         -#show_memstats
   122    123   do_test memsubsys1-3.1.3 {
   123    124     set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
   124    125   } 0
   125    126   do_test memsubsys1-3.1.4 {
   126    127     set overflow [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
   127    128     # Note:  The measured PAGECACHE_OVERFLOW is amount malloc() returns, not what
   128    129     # was requested.  System malloc() implementations might (arbitrarily) return
................................................................................
   308    309   
   309    310   db close
   310    311   sqlite3_shutdown
   311    312   sqlite3_config_memstatus 1
   312    313   sqlite3_config_pagecache 0 0
   313    314   sqlite3_config_scratch 0 0
   314    315   sqlite3_config_lookaside 100 500
          316  +sqlite3_config serialized
   315    317   sqlite3_initialize
   316    318   autoinstall_test_functions
   317    319   finish_test

Changes to test/pcache2.test.

    20     20   # pages are being used for cache.
    21     21   #
    22     22   do_test pcache2-1.1 {
    23     23     db close
    24     24     sqlite3_reset_auto_extension
    25     25     sqlite3_shutdown
    26     26     sqlite3_config_pagecache 6000 100
           27  +  sqlite3_config singlethread
    27     28     sqlite3_initialize
    28     29     autoinstall_test_functions
    29     30     sqlite3_status SQLITE_STATUS_PAGECACHE_USED 1
    30     31     sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0
    31     32   } {0 0 0}
    32     33   
    33     34   # Open up two database connections to separate files.
................................................................................
    69     70   } {0 13 13}
    70     71   
    71     72   db close
    72     73   catch {db2 close}
    73     74   sqlite3_reset_auto_extension
    74     75   sqlite3_shutdown
    75     76   sqlite3_config_pagecache 0 0
           77  +sqlite3_config serialized
    76     78   sqlite3_initialize
    77     79   autoinstall_test_functions
    78     80   
    79     81   finish_test

Changes to test/speedtest1.c.

  1173   1173     int doIncrvac = 0;            /* True for --incrvacuum */
  1174   1174     const char *zJMode = 0;       /* Journal mode */
  1175   1175     const char *zKey = 0;         /* Encryption key */
  1176   1176     int nLook = 0, szLook = 0;    /* --lookaside configuration */
  1177   1177     int noSync = 0;               /* True for --nosync */
  1178   1178     int pageSize = 0;             /* Desired page size.  0 means default */
  1179   1179     int nPCache = 0, szPCache = 0;/* --pcache configuration */
         1180  +  int doPCache = 0;             /* True if --pcache is seen */
  1180   1181     int nScratch = 0, szScratch=0;/* --scratch configuration */
  1181   1182     int showStats = 0;            /* True for --stats */
  1182   1183     int nThread = 0;              /* --threads value */
  1183   1184     const char *zTSet = "main";   /* Which --testset torun */
  1184   1185     int doTrace = 0;              /* True for --trace */
  1185   1186     const char *zEncoding = 0;    /* --utf16be or --utf16le */
  1186   1187     const char *zDbName = 0;      /* Name of the test database */
................................................................................
  1247   1248         }else if( strcmp(z,"pagesize")==0 ){
  1248   1249           if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
  1249   1250           pageSize = integerValue(argv[++i]);
  1250   1251         }else if( strcmp(z,"pcache")==0 ){
  1251   1252           if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
  1252   1253           nPCache = integerValue(argv[i+1]);
  1253   1254           szPCache = integerValue(argv[i+2]);
         1255  +        doPCache = 1;
  1254   1256           i += 2;
  1255   1257         }else if( strcmp(z,"primarykey")==0 ){
  1256   1258           g.zPK = "PRIMARY KEY";
  1257   1259         }else if( strcmp(z,"reprepare")==0 ){
  1258   1260           g.bReprepare = 1;
  1259   1261         }else if( strcmp(z,"scratch")==0 ){
  1260   1262           if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
................................................................................
  1313   1315   #if SQLITE_VERSION_NUMBER>=3006001
  1314   1316     if( nHeap>0 ){
  1315   1317       pHeap = malloc( nHeap );
  1316   1318       if( pHeap==0 ) fatal_error("cannot allocate %d-byte heap\n", nHeap);
  1317   1319       rc = sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, mnHeap);
  1318   1320       if( rc ) fatal_error("heap configuration failed: %d\n", rc);
  1319   1321     }
  1320         -  if( nPCache>0 && szPCache>0 ){
  1321         -    pPCache = malloc( nPCache*(sqlite3_int64)szPCache );
  1322         -    if( pPCache==0 ) fatal_error("cannot allocate %lld-byte pcache\n",
  1323         -                                 nPCache*(sqlite3_int64)szPCache);
         1322  +  if( doPCache ){
         1323  +    if( nPCache>0 && szPCache>0 ){
         1324  +      pPCache = malloc( nPCache*(sqlite3_int64)szPCache );
         1325  +      if( pPCache==0 ) fatal_error("cannot allocate %lld-byte pcache\n",
         1326  +                                   nPCache*(sqlite3_int64)szPCache);
         1327  +    }
  1324   1328       rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache);
  1325   1329       if( rc ) fatal_error("pcache configuration failed: %d\n", rc);
  1326   1330     }
  1327   1331     if( nScratch>0 && szScratch>0 ){
  1328   1332       pScratch = malloc( nScratch*(sqlite3_int64)szScratch );
  1329   1333       if( pScratch==0 ) fatal_error("cannot allocate %lld-byte scratch\n",
  1330   1334                                    nScratch*(sqlite3_int64)szScratch);