Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: third_party/sqlite/sqlite-src-3080704/src/pcache1.c

Issue 883353008: [sql] Import reference version of SQLite 3.8.7.4. (Closed) Base URL: http://chromium.googlesource.com/chromium/src.git@master
Patch Set: Hold back encoding change which is messing up patch. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 ** 2008 November 05 2 ** 2008 November 05
3 ** 3 **
4 ** The author disclaims copyright to this source code. In place of 4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing: 5 ** a legal notice, here is a blessing:
6 ** 6 **
7 ** May you do good and not evil. 7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others. 8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give. 9 ** May you share freely, never taking more than you give.
10 ** 10 **
11 ************************************************************************* 11 *************************************************************************
12 ** 12 **
13 ** This file implements the default page cache implementation (the 13 ** This file implements the default page cache implementation (the
14 ** sqlite3_pcache interface). It also contains part of the implementation 14 ** sqlite3_pcache interface). It also contains part of the implementation
15 ** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features. 15 ** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features.
16 ** If the default page cache implementation is overriden, then neither of 16 ** If the default page cache implementation is overridden, then neither of
17 ** these two features are available. 17 ** these two features are available.
18 */ 18 */
19 19
20 #include "sqliteInt.h" 20 #include "sqliteInt.h"
21 21
22 typedef struct PCache1 PCache1; 22 typedef struct PCache1 PCache1;
23 typedef struct PgHdr1 PgHdr1; 23 typedef struct PgHdr1 PgHdr1;
24 typedef struct PgFreeslot PgFreeslot; 24 typedef struct PgFreeslot PgFreeslot;
25 typedef struct PGroup PGroup; 25 typedef struct PGroup PGroup;
26 26
27 /* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set 27 /* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set
28 ** of one or more PCaches that are able to recycle each others unpinned 28 ** of one or more PCaches that are able to recycle each other's unpinned
29 ** pages when they are under memory pressure. A PGroup is an instance of 29 ** pages when they are under memory pressure. A PGroup is an instance of
30 ** the following object. 30 ** the following object.
31 ** 31 **
32 ** This page cache implementation works in one of two modes: 32 ** This page cache implementation works in one of two modes:
33 ** 33 **
34 ** (1) Every PCache is the sole member of its own PGroup. There is 34 ** (1) Every PCache is the sole member of its own PGroup. There is
35 ** one PGroup per PCache. 35 ** one PGroup per PCache.
36 ** 36 **
37 ** (2) There is a single global PGroup that all PCaches are a member 37 ** (2) There is a single global PGroup that all PCaches are a member
38 ** of. 38 ** of.
39 ** 39 **
40 ** Mode 1 uses more memory (since PCache instances are not able to rob 40 ** Mode 1 uses more memory (since PCache instances are not able to rob
41 ** unused pages from other PCaches) but it also operates without a mutex, 41 ** unused pages from other PCaches) but it also operates without a mutex,
42 ** and is therefore often faster. Mode 2 requires a mutex in order to be 42 ** and is therefore often faster. Mode 2 requires a mutex in order to be
43 ** threadsafe, but is able recycle pages more efficient. 43 ** threadsafe, but recycles pages more efficiently.
44 ** 44 **
45 ** For mode (1), PGroup.mutex is NULL. For mode (2) there is only a single 45 ** For mode (1), PGroup.mutex is NULL. For mode (2) there is only a single
46 ** PGroup which is the pcache1.grp global variable and its mutex is 46 ** PGroup which is the pcache1.grp global variable and its mutex is
47 ** SQLITE_MUTEX_STATIC_LRU. 47 ** SQLITE_MUTEX_STATIC_LRU.
48 */ 48 */
49 struct PGroup { 49 struct PGroup {
50 sqlite3_mutex *mutex; /* MUTEX_STATIC_LRU or NULL */ 50 sqlite3_mutex *mutex; /* MUTEX_STATIC_LRU or NULL */
51 int nMaxPage; /* Sum of nMax for purgeable caches */ 51 unsigned int nMaxPage; /* Sum of nMax for purgeable caches */
52 int nMinPage; /* Sum of nMin for purgeable caches */ 52 unsigned int nMinPage; /* Sum of nMin for purgeable caches */
53 int mxPinned; /* nMaxpage + 10 - nMinPage */ 53 unsigned int mxPinned; /* nMaxpage + 10 - nMinPage */
54 int nCurrentPage; /* Number of purgeable pages allocated */ 54 unsigned int nCurrentPage; /* Number of purgeable pages allocated */
55 PgHdr1 *pLruHead, *pLruTail; /* LRU list of unpinned pages */ 55 PgHdr1 *pLruHead, *pLruTail; /* LRU list of unpinned pages */
56 }; 56 };
57 57
58 /* Each page cache is an instance of the following object. Every 58 /* Each page cache is an instance of the following object. Every
59 ** open database file (including each in-memory database and each 59 ** open database file (including each in-memory database and each
60 ** temporary or transient database) has a single page cache which 60 ** temporary or transient database) has a single page cache which
61 ** is an instance of this object. 61 ** is an instance of this object.
62 ** 62 **
63 ** Pointers to structures of this type are cast and returned as 63 ** Pointers to structures of this type are cast and returned as
64 ** opaque sqlite3_pcache* handles. 64 ** opaque sqlite3_pcache* handles.
65 */ 65 */
66 struct PCache1 { 66 struct PCache1 {
67 /* Cache configuration parameters. Page size (szPage) and the purgeable 67 /* Cache configuration parameters. Page size (szPage) and the purgeable
68 ** flag (bPurgeable) are set when the cache is created. nMax may be 68 ** flag (bPurgeable) are set when the cache is created. nMax may be
69 ** modified at any time by a call to the pcache1CacheSize() method. 69 ** modified at any time by a call to the pcache1Cachesize() method.
70 ** The PGroup mutex must be held when accessing nMax. 70 ** The PGroup mutex must be held when accessing nMax.
71 */ 71 */
72 PGroup *pGroup; /* PGroup this cache belongs to */ 72 PGroup *pGroup; /* PGroup this cache belongs to */
73 int szPage; /* Size of allocated pages in bytes */ 73 int szPage; /* Size of allocated pages in bytes */
74 int szExtra; /* Size of extra space in bytes */
74 int bPurgeable; /* True if cache is purgeable */ 75 int bPurgeable; /* True if cache is purgeable */
75 unsigned int nMin; /* Minimum number of pages reserved */ 76 unsigned int nMin; /* Minimum number of pages reserved */
76 unsigned int nMax; /* Configured "cache_size" value */ 77 unsigned int nMax; /* Configured "cache_size" value */
77 unsigned int n90pct; /* nMax*9/10 */ 78 unsigned int n90pct; /* nMax*9/10 */
79 unsigned int iMaxKey; /* Largest key seen since xTruncate() */
78 80
79 /* Hash table of all pages. The following variables may only be accessed 81 /* Hash table of all pages. The following variables may only be accessed
80 ** when the accessor is holding the PGroup mutex. 82 ** when the accessor is holding the PGroup mutex.
81 */ 83 */
82 unsigned int nRecyclable; /* Number of pages in the LRU list */ 84 unsigned int nRecyclable; /* Number of pages in the LRU list */
83 unsigned int nPage; /* Total number of pages in apHash */ 85 unsigned int nPage; /* Total number of pages in apHash */
84 unsigned int nHash; /* Number of slots in apHash[] */ 86 unsigned int nHash; /* Number of slots in apHash[] */
85 PgHdr1 **apHash; /* Hash table for fast lookup by key */ 87 PgHdr1 **apHash; /* Hash table for fast lookup by key */
86
87 unsigned int iMaxKey; /* Largest key seen since xTruncate() */
88 }; 88 };
89 89
90 /* 90 /*
91 ** Each cache entry is represented by an instance of the following 91 ** Each cache entry is represented by an instance of the following
92 ** structure. A buffer of PgHdr1.pCache->szPage bytes is allocated 92 ** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
93 ** directly before this structure in memory (see the PGHDR1_TO_PAGE() 93 ** PgHdr1.pCache->szPage bytes is allocated directly before this structure
94 ** macro below). 94 ** in memory.
95 */ 95 */
96 struct PgHdr1 { 96 struct PgHdr1 {
97 sqlite3_pcache_page page;
97 unsigned int iKey; /* Key value (page number) */ 98 unsigned int iKey; /* Key value (page number) */
99 u8 isPinned; /* Page in use, not on the LRU list */
98 PgHdr1 *pNext; /* Next in hash table chain */ 100 PgHdr1 *pNext; /* Next in hash table chain */
99 PCache1 *pCache; /* Cache that currently owns this page */ 101 PCache1 *pCache; /* Cache that currently owns this page */
100 PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */ 102 PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */
101 PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */ 103 PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */
102 }; 104 };
103 105
104 /* 106 /*
105 ** Free slots in the allocator used to divide up the buffer provided using 107 ** Free slots in the allocator used to divide up the buffer provided using
106 ** the SQLITE_CONFIG_PAGECACHE mechanism. 108 ** the SQLITE_CONFIG_PAGECACHE mechanism.
107 */ 109 */
(...skipping 12 matching lines...) Expand all
120 ** fixed at sqlite3_initialize() time and do not require mutex protection. 122 ** fixed at sqlite3_initialize() time and do not require mutex protection.
121 ** The nFreeSlot and pFree values do require mutex protection. 123 ** The nFreeSlot and pFree values do require mutex protection.
122 */ 124 */
123 int isInit; /* True if initialized */ 125 int isInit; /* True if initialized */
124 int szSlot; /* Size of each free slot */ 126 int szSlot; /* Size of each free slot */
125 int nSlot; /* The number of pcache slots */ 127 int nSlot; /* The number of pcache slots */
126 int nReserve; /* Try to keep nFreeSlot above this */ 128 int nReserve; /* Try to keep nFreeSlot above this */
127 void *pStart, *pEnd; /* Bounds of pagecache malloc range */ 129 void *pStart, *pEnd; /* Bounds of pagecache malloc range */
128 /* Above requires no mutex. Use mutex below for variable that follow. */ 130 /* Above requires no mutex. Use mutex below for variable that follow. */
129 sqlite3_mutex *mutex; /* Mutex for accessing the following: */ 131 sqlite3_mutex *mutex; /* Mutex for accessing the following: */
132 PgFreeslot *pFree; /* Free page blocks */
130 int nFreeSlot; /* Number of unused pcache slots */ 133 int nFreeSlot; /* Number of unused pcache slots */
131 PgFreeslot *pFree; /* Free page blocks */
132 /* The following value requires a mutex to change. We skip the mutex on 134 /* The following value requires a mutex to change. We skip the mutex on
133 ** reading because (1) most platforms read a 32-bit integer atomically and 135 ** reading because (1) most platforms read a 32-bit integer atomically and
134 ** (2) even if an incorrect value is read, no great harm is done since this 136 ** (2) even if an incorrect value is read, no great harm is done since this
135 ** is really just an optimization. */ 137 ** is really just an optimization. */
136 int bUnderPressure; /* True if low on PAGECACHE memory */ 138 int bUnderPressure; /* True if low on PAGECACHE memory */
137 } pcache1_g; 139 } pcache1_g;
138 140
139 /* 141 /*
140 ** All code in this file should access the global structure above via the 142 ** All code in this file should access the global structure above via the
141 ** alias "pcache1". This ensures that the WSD emulation is used when 143 ** alias "pcache1". This ensures that the WSD emulation is used when
142 ** compiling for systems that do not support real WSD. 144 ** compiling for systems that do not support real WSD.
143 */ 145 */
144 #define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g)) 146 #define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g))
145 147
146 /* 148 /*
147 ** When a PgHdr1 structure is allocated, the associated PCache1.szPage
148 ** bytes of data are located directly before it in memory (i.e. the total
149 ** size of the allocation is sizeof(PgHdr1)+PCache1.szPage byte). The
150 ** PGHDR1_TO_PAGE() macro takes a pointer to a PgHdr1 structure as
151 ** an argument and returns a pointer to the associated block of szPage
152 ** bytes. The PAGE_TO_PGHDR1() macro does the opposite: its argument is
153 ** a pointer to a block of szPage bytes of data and the return value is
154 ** a pointer to the associated PgHdr1 structure.
155 **
156 ** assert( PGHDR1_TO_PAGE(PAGE_TO_PGHDR1(pCache, X))==X );
157 */
158 #define PGHDR1_TO_PAGE(p) (void*)(((char*)p) - p->pCache->szPage)
159 #define PAGE_TO_PGHDR1(c, p) (PgHdr1*)(((char*)p) + c->szPage)
160
161 /*
162 ** Macros to enter and leave the PCache LRU mutex. 149 ** Macros to enter and leave the PCache LRU mutex.
163 */ 150 */
164 #define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex) 151 #define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex)
165 #define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex) 152 #define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex)
166 153
167 /******************************************************************************/ 154 /******************************************************************************/
168 /******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/ 155 /******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/
169 156
170 /* 157 /*
171 ** This function is called during initialization if a static buffer is 158 ** This function is called during initialization if a static buffer is
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 assert( pcache1.nFreeSlot>=0 ); 206 assert( pcache1.nFreeSlot>=0 );
220 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1); 207 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1);
221 } 208 }
222 sqlite3_mutex_leave(pcache1.mutex); 209 sqlite3_mutex_leave(pcache1.mutex);
223 } 210 }
224 if( p==0 ){ 211 if( p==0 ){
225 /* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool. Get 212 /* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool. Get
226 ** it from sqlite3Malloc instead. 213 ** it from sqlite3Malloc instead.
227 */ 214 */
228 p = sqlite3Malloc(nByte); 215 p = sqlite3Malloc(nByte);
216 #ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
229 if( p ){ 217 if( p ){
230 int sz = sqlite3MallocSize(p); 218 int sz = sqlite3MallocSize(p);
231 sqlite3_mutex_enter(pcache1.mutex); 219 sqlite3_mutex_enter(pcache1.mutex);
232 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz); 220 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
233 sqlite3_mutex_leave(pcache1.mutex); 221 sqlite3_mutex_leave(pcache1.mutex);
234 } 222 }
223 #endif
235 sqlite3MemdebugSetType(p, MEMTYPE_PCACHE); 224 sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
236 } 225 }
237 return p; 226 return p;
238 } 227 }
239 228
240 /* 229 /*
241 ** Free an allocated buffer obtained from pcache1Alloc(). 230 ** Free an allocated buffer obtained from pcache1Alloc().
242 */ 231 */
243 static void pcache1Free(void *p){ 232 static int pcache1Free(void *p){
244 if( p==0 ) return; 233 int nFreed = 0;
234 if( p==0 ) return 0;
245 if( p>=pcache1.pStart && p<pcache1.pEnd ){ 235 if( p>=pcache1.pStart && p<pcache1.pEnd ){
246 PgFreeslot *pSlot; 236 PgFreeslot *pSlot;
247 sqlite3_mutex_enter(pcache1.mutex); 237 sqlite3_mutex_enter(pcache1.mutex);
248 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1); 238 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1);
249 pSlot = (PgFreeslot*)p; 239 pSlot = (PgFreeslot*)p;
250 pSlot->pNext = pcache1.pFree; 240 pSlot->pNext = pcache1.pFree;
251 pcache1.pFree = pSlot; 241 pcache1.pFree = pSlot;
252 pcache1.nFreeSlot++; 242 pcache1.nFreeSlot++;
253 pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve; 243 pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
254 assert( pcache1.nFreeSlot<=pcache1.nSlot ); 244 assert( pcache1.nFreeSlot<=pcache1.nSlot );
255 sqlite3_mutex_leave(pcache1.mutex); 245 sqlite3_mutex_leave(pcache1.mutex);
256 }else{ 246 }else{
257 int iSize;
258 assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) ); 247 assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
259 sqlite3MemdebugSetType(p, MEMTYPE_HEAP); 248 sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
260 iSize = sqlite3MallocSize(p); 249 nFreed = sqlite3MallocSize(p);
250 #ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
261 sqlite3_mutex_enter(pcache1.mutex); 251 sqlite3_mutex_enter(pcache1.mutex);
262 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -iSize); 252 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -nFreed);
263 sqlite3_mutex_leave(pcache1.mutex); 253 sqlite3_mutex_leave(pcache1.mutex);
254 #endif
264 sqlite3_free(p); 255 sqlite3_free(p);
265 } 256 }
257 return nFreed;
266 } 258 }
267 259
268 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT 260 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
269 /* 261 /*
270 ** Return the size of a pcache allocation 262 ** Return the size of a pcache allocation
271 */ 263 */
272 static int pcache1MemSize(void *p){ 264 static int pcache1MemSize(void *p){
273 if( p>=pcache1.pStart && p<pcache1.pEnd ){ 265 if( p>=pcache1.pStart && p<pcache1.pEnd ){
274 return pcache1.szSlot; 266 return pcache1.szSlot;
275 }else{ 267 }else{
276 int iSize; 268 int iSize;
277 assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) ); 269 assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
278 sqlite3MemdebugSetType(p, MEMTYPE_HEAP); 270 sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
279 iSize = sqlite3MallocSize(p); 271 iSize = sqlite3MallocSize(p);
280 sqlite3MemdebugSetType(p, MEMTYPE_PCACHE); 272 sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
281 return iSize; 273 return iSize;
282 } 274 }
283 } 275 }
284 #endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */ 276 #endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
285 277
286 /* 278 /*
287 ** Allocate a new page object initially associated with cache pCache. 279 ** Allocate a new page object initially associated with cache pCache.
288 */ 280 */
289 static PgHdr1 *pcache1AllocPage(PCache1 *pCache){ 281 static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
290 int nByte = sizeof(PgHdr1) + pCache->szPage; 282 PgHdr1 *p = 0;
291 void *pPg = pcache1Alloc(nByte); 283 void *pPg;
292 PgHdr1 *p; 284
285 /* The group mutex must be released before pcache1Alloc() is called. This
286 ** is because it may call sqlite3_release_memory(), which assumes that
287 ** this mutex is not held. */
288 assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
289 pcache1LeaveMutex(pCache->pGroup);
290 #ifdef SQLITE_PCACHE_SEPARATE_HEADER
291 pPg = pcache1Alloc(pCache->szPage);
292 p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
293 if( !pPg || !p ){
294 pcache1Free(pPg);
295 sqlite3_free(p);
296 pPg = 0;
297 }
298 #else
299 pPg = pcache1Alloc(sizeof(PgHdr1) + pCache->szPage + pCache->szExtra);
300 p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
301 #endif
302 pcache1EnterMutex(pCache->pGroup);
303
293 if( pPg ){ 304 if( pPg ){
294 p = PAGE_TO_PGHDR1(pCache, pPg); 305 p->page.pBuf = pPg;
306 p->page.pExtra = &p[1];
295 if( pCache->bPurgeable ){ 307 if( pCache->bPurgeable ){
296 pCache->pGroup->nCurrentPage++; 308 pCache->pGroup->nCurrentPage++;
297 } 309 }
298 }else{ 310 return p;
299 p = 0;
300 } 311 }
301 return p; 312 return 0;
302 } 313 }
303 314
304 /* 315 /*
305 ** Free a page object allocated by pcache1AllocPage(). 316 ** Free a page object allocated by pcache1AllocPage().
306 ** 317 **
307 ** The pointer is allowed to be NULL, which is prudent. But it turns out 318 ** The pointer is allowed to be NULL, which is prudent. But it turns out
308 ** that the current implementation happens to never call this routine 319 ** that the current implementation happens to never call this routine
309 ** with a NULL pointer, so we mark the NULL test with ALWAYS(). 320 ** with a NULL pointer, so we mark the NULL test with ALWAYS().
310 */ 321 */
311 static void pcache1FreePage(PgHdr1 *p){ 322 static void pcache1FreePage(PgHdr1 *p){
312 if( ALWAYS(p) ){ 323 if( ALWAYS(p) ){
313 PCache1 *pCache = p->pCache; 324 PCache1 *pCache = p->pCache;
325 assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
326 pcache1Free(p->page.pBuf);
327 #ifdef SQLITE_PCACHE_SEPARATE_HEADER
328 sqlite3_free(p);
329 #endif
314 if( pCache->bPurgeable ){ 330 if( pCache->bPurgeable ){
315 pCache->pGroup->nCurrentPage--; 331 pCache->pGroup->nCurrentPage--;
316 } 332 }
317 pcache1Free(PGHDR1_TO_PAGE(p));
318 } 333 }
319 } 334 }
320 335
321 /* 336 /*
322 ** Malloc function used by SQLite to obtain space from the buffer configured 337 ** Malloc function used by SQLite to obtain space from the buffer configured
323 ** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer 338 ** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer
324 ** exists, this function falls back to sqlite3Malloc(). 339 ** exists, this function falls back to sqlite3Malloc().
325 */ 340 */
326 void *sqlite3PageMalloc(int sz){ 341 void *sqlite3PageMalloc(int sz){
327 return pcache1Alloc(sz); 342 return pcache1Alloc(sz);
(...skipping 11 matching lines...) Expand all
339 ** Return true if it desirable to avoid allocating a new page cache 354 ** Return true if it desirable to avoid allocating a new page cache
340 ** entry. 355 ** entry.
341 ** 356 **
342 ** If memory was allocated specifically to the page cache using 357 ** If memory was allocated specifically to the page cache using
343 ** SQLITE_CONFIG_PAGECACHE but that memory has all been used, then 358 ** SQLITE_CONFIG_PAGECACHE but that memory has all been used, then
344 ** it is desirable to avoid allocating a new page cache entry because 359 ** it is desirable to avoid allocating a new page cache entry because
345 ** presumably SQLITE_CONFIG_PAGECACHE was suppose to be sufficient 360 ** presumably SQLITE_CONFIG_PAGECACHE was suppose to be sufficient
346 ** for all page cache needs and we should not need to spill the 361 ** for all page cache needs and we should not need to spill the
347 ** allocation onto the heap. 362 ** allocation onto the heap.
348 ** 363 **
349 ** Or, the heap is used for all page cache memory put the heap is 364 ** Or, the heap is used for all page cache memory but the heap is
350 ** under memory pressure, then again it is desirable to avoid 365 ** under memory pressure, then again it is desirable to avoid
351 ** allocating a new page cache entry in order to avoid stressing 366 ** allocating a new page cache entry in order to avoid stressing
352 ** the heap even further. 367 ** the heap even further.
353 */ 368 */
354 static int pcache1UnderMemoryPressure(PCache1 *pCache){ 369 static int pcache1UnderMemoryPressure(PCache1 *pCache){
355 if( pcache1.nSlot && pCache->szPage<=pcache1.szSlot ){ 370 if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){
356 return pcache1.bUnderPressure; 371 return pcache1.bUnderPressure;
357 }else{ 372 }else{
358 return sqlite3HeapNearlyFull(); 373 return sqlite3HeapNearlyFull();
359 } 374 }
360 } 375 }
361 376
362 /******************************************************************************/ 377 /******************************************************************************/
363 /******** General Implementation Functions ************************************/ 378 /******** General Implementation Functions ************************************/
364 379
365 /* 380 /*
366 ** This function is used to resize the hash table used by the cache passed 381 ** This function is used to resize the hash table used by the cache passed
367 ** as the first argument. 382 ** as the first argument.
368 ** 383 **
369 ** The PCache mutex must be held when this function is called. 384 ** The PCache mutex must be held when this function is called.
370 */ 385 */
371 static int pcache1ResizeHash(PCache1 *p){ 386 static void pcache1ResizeHash(PCache1 *p){
372 PgHdr1 **apNew; 387 PgHdr1 **apNew;
373 unsigned int nNew; 388 unsigned int nNew;
374 unsigned int i; 389 unsigned int i;
375 390
376 assert( sqlite3_mutex_held(p->pGroup->mutex) ); 391 assert( sqlite3_mutex_held(p->pGroup->mutex) );
377 392
378 nNew = p->nHash*2; 393 nNew = p->nHash*2;
379 if( nNew<256 ){ 394 if( nNew<256 ){
380 nNew = 256; 395 nNew = 256;
381 } 396 }
382 397
383 pcache1LeaveMutex(p->pGroup); 398 pcache1LeaveMutex(p->pGroup);
384 if( p->nHash ){ sqlite3BeginBenignMalloc(); } 399 if( p->nHash ){ sqlite3BeginBenignMalloc(); }
385 apNew = (PgHdr1 **)sqlite3_malloc(sizeof(PgHdr1 *)*nNew); 400 apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew);
386 if( p->nHash ){ sqlite3EndBenignMalloc(); } 401 if( p->nHash ){ sqlite3EndBenignMalloc(); }
387 pcache1EnterMutex(p->pGroup); 402 pcache1EnterMutex(p->pGroup);
388 if( apNew ){ 403 if( apNew ){
389 memset(apNew, 0, sizeof(PgHdr1 *)*nNew);
390 for(i=0; i<p->nHash; i++){ 404 for(i=0; i<p->nHash; i++){
391 PgHdr1 *pPage; 405 PgHdr1 *pPage;
392 PgHdr1 *pNext = p->apHash[i]; 406 PgHdr1 *pNext = p->apHash[i];
393 while( (pPage = pNext)!=0 ){ 407 while( (pPage = pNext)!=0 ){
394 unsigned int h = pPage->iKey % nNew; 408 unsigned int h = pPage->iKey % nNew;
395 pNext = pPage->pNext; 409 pNext = pPage->pNext;
396 pPage->pNext = apNew[h]; 410 pPage->pNext = apNew[h];
397 apNew[h] = pPage; 411 apNew[h] = pPage;
398 } 412 }
399 } 413 }
400 sqlite3_free(p->apHash); 414 sqlite3_free(p->apHash);
401 p->apHash = apNew; 415 p->apHash = apNew;
402 p->nHash = nNew; 416 p->nHash = nNew;
403 } 417 }
404
405 return (p->apHash ? SQLITE_OK : SQLITE_NOMEM);
406 } 418 }
407 419
408 /* 420 /*
409 ** This function is used internally to remove the page pPage from the 421 ** This function is used internally to remove the page pPage from the
410 ** PGroup LRU list, if is part of it. If pPage is not part of the PGroup 422 ** PGroup LRU list, if is part of it. If pPage is not part of the PGroup
411 ** LRU list, then this function is a no-op. 423 ** LRU list, then this function is a no-op.
412 ** 424 **
413 ** The PGroup mutex must be held when this function is called. 425 ** The PGroup mutex must be held when this function is called.
414 **
415 ** If pPage is NULL then this routine is a no-op.
416 */ 426 */
417 static void pcache1PinPage(PgHdr1 *pPage){ 427 static void pcache1PinPage(PgHdr1 *pPage){
418 PCache1 *pCache; 428 PCache1 *pCache;
419 PGroup *pGroup; 429 PGroup *pGroup;
420 430
421 if( pPage==0 ) return; 431 assert( pPage!=0 );
432 assert( pPage->isPinned==0 );
422 pCache = pPage->pCache; 433 pCache = pPage->pCache;
423 pGroup = pCache->pGroup; 434 pGroup = pCache->pGroup;
435 assert( pPage->pLruNext || pPage==pGroup->pLruTail );
436 assert( pPage->pLruPrev || pPage==pGroup->pLruHead );
424 assert( sqlite3_mutex_held(pGroup->mutex) ); 437 assert( sqlite3_mutex_held(pGroup->mutex) );
425 if( pPage->pLruNext || pPage==pGroup->pLruTail ){ 438 if( pPage->pLruPrev ){
426 if( pPage->pLruPrev ){ 439 pPage->pLruPrev->pLruNext = pPage->pLruNext;
427 pPage->pLruPrev->pLruNext = pPage->pLruNext; 440 }else{
428 } 441 pGroup->pLruHead = pPage->pLruNext;
429 if( pPage->pLruNext ){
430 pPage->pLruNext->pLruPrev = pPage->pLruPrev;
431 }
432 if( pGroup->pLruHead==pPage ){
433 pGroup->pLruHead = pPage->pLruNext;
434 }
435 if( pGroup->pLruTail==pPage ){
436 pGroup->pLruTail = pPage->pLruPrev;
437 }
438 pPage->pLruNext = 0;
439 pPage->pLruPrev = 0;
440 pPage->pCache->nRecyclable--;
441 } 442 }
443 if( pPage->pLruNext ){
444 pPage->pLruNext->pLruPrev = pPage->pLruPrev;
445 }else{
446 pGroup->pLruTail = pPage->pLruPrev;
447 }
448 pPage->pLruNext = 0;
449 pPage->pLruPrev = 0;
450 pPage->isPinned = 1;
451 pCache->nRecyclable--;
442 } 452 }
443 453
444 454
445 /* 455 /*
446 ** Remove the page supplied as an argument from the hash table 456 ** Remove the page supplied as an argument from the hash table
447 ** (PCache1.apHash structure) that it is currently stored in. 457 ** (PCache1.apHash structure) that it is currently stored in.
448 ** 458 **
449 ** The PGroup mutex must be held when this function is called. 459 ** The PGroup mutex must be held when this function is called.
450 */ 460 */
451 static void pcache1RemoveFromHash(PgHdr1 *pPage){ 461 static void pcache1RemoveFromHash(PgHdr1 *pPage){
(...skipping 11 matching lines...) Expand all
463 473
464 /* 474 /*
465 ** If there are currently more than nMaxPage pages allocated, try 475 ** If there are currently more than nMaxPage pages allocated, try
466 ** to recycle pages to reduce the number allocated to nMaxPage. 476 ** to recycle pages to reduce the number allocated to nMaxPage.
467 */ 477 */
468 static void pcache1EnforceMaxPage(PGroup *pGroup){ 478 static void pcache1EnforceMaxPage(PGroup *pGroup){
469 assert( sqlite3_mutex_held(pGroup->mutex) ); 479 assert( sqlite3_mutex_held(pGroup->mutex) );
470 while( pGroup->nCurrentPage>pGroup->nMaxPage && pGroup->pLruTail ){ 480 while( pGroup->nCurrentPage>pGroup->nMaxPage && pGroup->pLruTail ){
471 PgHdr1 *p = pGroup->pLruTail; 481 PgHdr1 *p = pGroup->pLruTail;
472 assert( p->pCache->pGroup==pGroup ); 482 assert( p->pCache->pGroup==pGroup );
483 assert( p->isPinned==0 );
473 pcache1PinPage(p); 484 pcache1PinPage(p);
474 pcache1RemoveFromHash(p); 485 pcache1RemoveFromHash(p);
475 pcache1FreePage(p); 486 pcache1FreePage(p);
476 } 487 }
477 } 488 }
478 489
479 /* 490 /*
480 ** Discard all pages from cache pCache with a page number (key value) 491 ** Discard all pages from cache pCache with a page number (key value)
481 ** greater than or equal to iLimit. Any pinned pages that meet this 492 ** greater than or equal to iLimit. Any pinned pages that meet this
482 ** criteria are unpinned before they are discarded. 493 ** criteria are unpinned before they are discarded.
483 ** 494 **
484 ** The PCache mutex must be held when this function is called. 495 ** The PCache mutex must be held when this function is called.
485 */ 496 */
486 static void pcache1TruncateUnsafe( 497 static void pcache1TruncateUnsafe(
487 PCache1 *pCache, /* The cache to truncate */ 498 PCache1 *pCache, /* The cache to truncate */
488 unsigned int iLimit /* Drop pages with this pgno or larger */ 499 unsigned int iLimit /* Drop pages with this pgno or larger */
489 ){ 500 ){
490 TESTONLY( unsigned int nPage = 0; ) /* To assert pCache->nPage is correct */ 501 TESTONLY( unsigned int nPage = 0; ) /* To assert pCache->nPage is correct */
491 unsigned int h; 502 unsigned int h;
492 assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); 503 assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
493 for(h=0; h<pCache->nHash; h++){ 504 for(h=0; h<pCache->nHash; h++){
494 PgHdr1 **pp = &pCache->apHash[h]; 505 PgHdr1 **pp = &pCache->apHash[h];
495 PgHdr1 *pPage; 506 PgHdr1 *pPage;
496 while( (pPage = *pp)!=0 ){ 507 while( (pPage = *pp)!=0 ){
497 if( pPage->iKey>=iLimit ){ 508 if( pPage->iKey>=iLimit ){
498 pCache->nPage--; 509 pCache->nPage--;
499 *pp = pPage->pNext; 510 *pp = pPage->pNext;
500 pcache1PinPage(pPage); 511 if( !pPage->isPinned ) pcache1PinPage(pPage);
501 pcache1FreePage(pPage); 512 pcache1FreePage(pPage);
502 }else{ 513 }else{
503 pp = &pPage->pNext; 514 pp = &pPage->pNext;
504 TESTONLY( nPage++; ) 515 TESTONLY( nPage++; )
505 } 516 }
506 } 517 }
507 } 518 }
508 assert( pCache->nPage==nPage ); 519 assert( pCache->nPage==nPage );
509 } 520 }
510 521
(...skipping 20 matching lines...) Expand all
531 ** Implementation of the sqlite3_pcache.xShutdown method. 542 ** Implementation of the sqlite3_pcache.xShutdown method.
532 ** Note that the static mutex allocated in xInit does 543 ** Note that the static mutex allocated in xInit does
533 ** not need to be freed. 544 ** not need to be freed.
534 */ 545 */
535 static void pcache1Shutdown(void *NotUsed){ 546 static void pcache1Shutdown(void *NotUsed){
536 UNUSED_PARAMETER(NotUsed); 547 UNUSED_PARAMETER(NotUsed);
537 assert( pcache1.isInit!=0 ); 548 assert( pcache1.isInit!=0 );
538 memset(&pcache1, 0, sizeof(pcache1)); 549 memset(&pcache1, 0, sizeof(pcache1));
539 } 550 }
540 551
552 /* forward declaration */
553 static void pcache1Destroy(sqlite3_pcache *p);
554
541 /* 555 /*
542 ** Implementation of the sqlite3_pcache.xCreate method. 556 ** Implementation of the sqlite3_pcache.xCreate method.
543 ** 557 **
544 ** Allocate a new cache. 558 ** Allocate a new cache.
545 */ 559 */
546 static sqlite3_pcache *pcache1Create(int szPage, int bPurgeable){ 560 static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
547 PCache1 *pCache; /* The newly created page cache */ 561 PCache1 *pCache; /* The newly created page cache */
548 PGroup *pGroup; /* The group the new page cache will belong to */ 562 PGroup *pGroup; /* The group the new page cache will belong to */
549 int sz; /* Bytes of memory required to allocate the new cache */ 563 int sz; /* Bytes of memory required to allocate the new cache */
550 564
551 /* 565 /*
552 ** The seperateCache variable is true if each PCache has its own private 566 ** The separateCache variable is true if each PCache has its own private
553 ** PGroup. In other words, separateCache is true for mode (1) where no 567 ** PGroup. In other words, separateCache is true for mode (1) where no
554 ** mutexing is required. 568 ** mutexing is required.
555 ** 569 **
556 ** * Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT 570 ** * Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT
557 ** 571 **
558 ** * Always use a unified cache in single-threaded applications 572 ** * Always use a unified cache in single-threaded applications
559 ** 573 **
560 ** * Otherwise (if multi-threaded and ENABLE_MEMORY_MANAGEMENT is off) 574 ** * Otherwise (if multi-threaded and ENABLE_MEMORY_MANAGEMENT is off)
561 ** use separate caches (mode-1) 575 ** use separate caches (mode-1)
562 */ 576 */
563 #if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0 577 #if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0
564 const int separateCache = 0; 578 const int separateCache = 0;
565 #else 579 #else
566 int separateCache = sqlite3GlobalConfig.bCoreMutex>0; 580 int separateCache = sqlite3GlobalConfig.bCoreMutex>0;
567 #endif 581 #endif
568 582
583 assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 );
584 assert( szExtra < 300 );
585
569 sz = sizeof(PCache1) + sizeof(PGroup)*separateCache; 586 sz = sizeof(PCache1) + sizeof(PGroup)*separateCache;
570 pCache = (PCache1 *)sqlite3_malloc(sz); 587 pCache = (PCache1 *)sqlite3MallocZero(sz);
571 if( pCache ){ 588 if( pCache ){
572 memset(pCache, 0, sz);
573 if( separateCache ){ 589 if( separateCache ){
574 pGroup = (PGroup*)&pCache[1]; 590 pGroup = (PGroup*)&pCache[1];
575 pGroup->mxPinned = 10; 591 pGroup->mxPinned = 10;
576 }else{ 592 }else{
577 pGroup = &pcache1_g.grp; 593 pGroup = &pcache1.grp;
578 } 594 }
579 pCache->pGroup = pGroup; 595 pCache->pGroup = pGroup;
580 pCache->szPage = szPage; 596 pCache->szPage = szPage;
597 pCache->szExtra = szExtra;
581 pCache->bPurgeable = (bPurgeable ? 1 : 0); 598 pCache->bPurgeable = (bPurgeable ? 1 : 0);
599 pcache1EnterMutex(pGroup);
600 pcache1ResizeHash(pCache);
582 if( bPurgeable ){ 601 if( bPurgeable ){
583 pCache->nMin = 10; 602 pCache->nMin = 10;
584 pcache1EnterMutex(pGroup);
585 pGroup->nMinPage += pCache->nMin; 603 pGroup->nMinPage += pCache->nMin;
586 pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; 604 pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
587 pcache1LeaveMutex(pGroup); 605 }
606 pcache1LeaveMutex(pGroup);
607 if( pCache->nHash==0 ){
608 pcache1Destroy((sqlite3_pcache*)pCache);
609 pCache = 0;
588 } 610 }
589 } 611 }
590 return (sqlite3_pcache *)pCache; 612 return (sqlite3_pcache *)pCache;
591 } 613 }
592 614
593 /* 615 /*
594 ** Implementation of the sqlite3_pcache.xCachesize method. 616 ** Implementation of the sqlite3_pcache.xCachesize method.
595 ** 617 **
596 ** Configure the cache_size limit for a cache. 618 ** Configure the cache_size limit for a cache.
597 */ 619 */
598 static void pcache1Cachesize(sqlite3_pcache *p, int nMax){ 620 static void pcache1Cachesize(sqlite3_pcache *p, int nMax){
599 PCache1 *pCache = (PCache1 *)p; 621 PCache1 *pCache = (PCache1 *)p;
600 if( pCache->bPurgeable ){ 622 if( pCache->bPurgeable ){
601 PGroup *pGroup = pCache->pGroup; 623 PGroup *pGroup = pCache->pGroup;
602 pcache1EnterMutex(pGroup); 624 pcache1EnterMutex(pGroup);
603 pGroup->nMaxPage += (nMax - pCache->nMax); 625 pGroup->nMaxPage += (nMax - pCache->nMax);
604 pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; 626 pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
605 pCache->nMax = nMax; 627 pCache->nMax = nMax;
606 pCache->n90pct = pCache->nMax*9/10; 628 pCache->n90pct = pCache->nMax*9/10;
607 pcache1EnforceMaxPage(pGroup); 629 pcache1EnforceMaxPage(pGroup);
608 pcache1LeaveMutex(pGroup); 630 pcache1LeaveMutex(pGroup);
609 } 631 }
610 } 632 }
611 633
612 /* 634 /*
635 ** Implementation of the sqlite3_pcache.xShrink method.
636 **
637 ** Free up as much memory as possible.
638 */
639 static void pcache1Shrink(sqlite3_pcache *p){
640 PCache1 *pCache = (PCache1*)p;
641 if( pCache->bPurgeable ){
642 PGroup *pGroup = pCache->pGroup;
643 int savedMaxPage;
644 pcache1EnterMutex(pGroup);
645 savedMaxPage = pGroup->nMaxPage;
646 pGroup->nMaxPage = 0;
647 pcache1EnforceMaxPage(pGroup);
648 pGroup->nMaxPage = savedMaxPage;
649 pcache1LeaveMutex(pGroup);
650 }
651 }
652
653 /*
613 ** Implementation of the sqlite3_pcache.xPagecount method. 654 ** Implementation of the sqlite3_pcache.xPagecount method.
614 */ 655 */
615 static int pcache1Pagecount(sqlite3_pcache *p){ 656 static int pcache1Pagecount(sqlite3_pcache *p){
616 int n; 657 int n;
617 PCache1 *pCache = (PCache1*)p; 658 PCache1 *pCache = (PCache1*)p;
618 pcache1EnterMutex(pCache->pGroup); 659 pcache1EnterMutex(pCache->pGroup);
619 n = pCache->nPage; 660 n = pCache->nPage;
620 pcache1LeaveMutex(pCache->pGroup); 661 pcache1LeaveMutex(pCache->pGroup);
621 return n; 662 return n;
622 } 663 }
623 664
665
666 /*
667 ** Implement steps 3, 4, and 5 of the pcache1Fetch() algorithm described
668 ** in the header of the pcache1Fetch() procedure.
669 **
670 ** This steps are broken out into a separate procedure because they are
671 ** usually not needed, and by avoiding the stack initialization required
672 ** for these steps, the main pcache1Fetch() procedure can run faster.
673 */
674 static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
675 PCache1 *pCache,
676 unsigned int iKey,
677 int createFlag
678 ){
679 unsigned int nPinned;
680 PGroup *pGroup = pCache->pGroup;
681 PgHdr1 *pPage = 0;
682
683 /* Step 3: Abort if createFlag is 1 but the cache is nearly full */
684 assert( pCache->nPage >= pCache->nRecyclable );
685 nPinned = pCache->nPage - pCache->nRecyclable;
686 assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
687 assert( pCache->n90pct == pCache->nMax*9/10 );
688 if( createFlag==1 && (
689 nPinned>=pGroup->mxPinned
690 || nPinned>=pCache->n90pct
691 || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclable<nPinned)
692 )){
693 return 0;
694 }
695
696 if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
697 assert( pCache->nHash>0 && pCache->apHash );
698
699 /* Step 4. Try to recycle a page. */
700 if( pCache->bPurgeable && pGroup->pLruTail && (
701 (pCache->nPage+1>=pCache->nMax)
702 || pGroup->nCurrentPage>=pGroup->nMaxPage
703 || pcache1UnderMemoryPressure(pCache)
704 )){
705 PCache1 *pOther;
706 pPage = pGroup->pLruTail;
707 assert( pPage->isPinned==0 );
708 pcache1RemoveFromHash(pPage);
709 pcache1PinPage(pPage);
710 pOther = pPage->pCache;
711
712 /* We want to verify that szPage and szExtra are the same for pOther
713 ** and pCache. Assert that we can verify this by comparing sums. */
714 assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 );
715 assert( pCache->szExtra<512 );
716 assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 );
717 assert( pOther->szExtra<512 );
718
719 if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){
720 pcache1FreePage(pPage);
721 pPage = 0;
722 }else{
723 pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable);
724 }
725 }
726
727 /* Step 5. If a usable page buffer has still not been found,
728 ** attempt to allocate a new one.
729 */
730 if( !pPage ){
731 if( createFlag==1 ) sqlite3BeginBenignMalloc();
732 pPage = pcache1AllocPage(pCache);
733 if( createFlag==1 ) sqlite3EndBenignMalloc();
734 }
735
736 if( pPage ){
737 unsigned int h = iKey % pCache->nHash;
738 pCache->nPage++;
739 pPage->iKey = iKey;
740 pPage->pNext = pCache->apHash[h];
741 pPage->pCache = pCache;
742 pPage->pLruPrev = 0;
743 pPage->pLruNext = 0;
744 pPage->isPinned = 1;
745 *(void **)pPage->page.pExtra = 0;
746 pCache->apHash[h] = pPage;
747 if( iKey>pCache->iMaxKey ){
748 pCache->iMaxKey = iKey;
749 }
750 }
751 return pPage;
752 }
753
624 /* 754 /*
625 ** Implementation of the sqlite3_pcache.xFetch method. 755 ** Implementation of the sqlite3_pcache.xFetch method.
626 ** 756 **
627 ** Fetch a page by key value. 757 ** Fetch a page by key value.
628 ** 758 **
629 ** Whether or not a new page may be allocated by this function depends on 759 ** Whether or not a new page may be allocated by this function depends on
630 ** the value of the createFlag argument. 0 means do not allocate a new 760 ** the value of the createFlag argument. 0 means do not allocate a new
631 ** page. 1 means allocate a new page if space is easily available. 2 761 ** page. 1 means allocate a new page if space is easily available. 2
632 ** means to try really hard to allocate a new page. 762 ** means to try really hard to allocate a new page.
633 ** 763 **
634 ** For a non-purgeable cache (a cache used as the storage for an in-memory 764 ** For a non-purgeable cache (a cache used as the storage for an in-memory
635 ** database) there is really no difference between createFlag 1 and 2. So 765 ** database) there is really no difference between createFlag 1 and 2. So
636 ** the calling function (pcache.c) will never have a createFlag of 1 on 766 ** the calling function (pcache.c) will never have a createFlag of 1 on
637 ** a non-purgable cache. 767 ** a non-purgeable cache.
638 ** 768 **
639 ** There are three different approaches to obtaining space for a page, 769 ** There are three different approaches to obtaining space for a page,
640 ** depending on the value of parameter createFlag (which may be 0, 1 or 2). 770 ** depending on the value of parameter createFlag (which may be 0, 1 or 2).
641 ** 771 **
642 ** 1. Regardless of the value of createFlag, the cache is searched for a 772 ** 1. Regardless of the value of createFlag, the cache is searched for a
643 ** copy of the requested page. If one is found, it is returned. 773 ** copy of the requested page. If one is found, it is returned.
644 ** 774 **
645 ** 2. If createFlag==0 and the page is not already in the cache, NULL is 775 ** 2. If createFlag==0 and the page is not already in the cache, NULL is
646 ** returned. 776 ** returned.
647 ** 777 **
(...skipping 20 matching lines...) Expand all
668 ** 798 **
669 ** (c) The system is under memory pressure and wants to avoid 799 ** (c) The system is under memory pressure and wants to avoid
670 ** unnecessary pages cache entry allocations 800 ** unnecessary pages cache entry allocations
671 ** 801 **
672 ** then attempt to recycle a page from the LRU list. If it is the right 802 ** then attempt to recycle a page from the LRU list. If it is the right
673 ** size, return the recycled buffer. Otherwise, free the buffer and 803 ** size, return the recycled buffer. Otherwise, free the buffer and
674 ** proceed to step 5. 804 ** proceed to step 5.
675 ** 805 **
676 ** 5. Otherwise, allocate and return a new page buffer. 806 ** 5. Otherwise, allocate and return a new page buffer.
677 */ 807 */
678 static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){ 808 static sqlite3_pcache_page *pcache1Fetch(
679 int nPinned; 809 sqlite3_pcache *p,
810 unsigned int iKey,
811 int createFlag
812 ){
680 PCache1 *pCache = (PCache1 *)p; 813 PCache1 *pCache = (PCache1 *)p;
681 PGroup *pGroup;
682 PgHdr1 *pPage = 0; 814 PgHdr1 *pPage = 0;
683 815
816 assert( offsetof(PgHdr1,page)==0 );
684 assert( pCache->bPurgeable || createFlag!=1 ); 817 assert( pCache->bPurgeable || createFlag!=1 );
685 assert( pCache->bPurgeable || pCache->nMin==0 ); 818 assert( pCache->bPurgeable || pCache->nMin==0 );
686 assert( pCache->bPurgeable==0 || pCache->nMin==10 ); 819 assert( pCache->bPurgeable==0 || pCache->nMin==10 );
687 assert( pCache->nMin==0 || pCache->bPurgeable ); 820 assert( pCache->nMin==0 || pCache->bPurgeable );
688 pcache1EnterMutex(pGroup = pCache->pGroup); 821 assert( pCache->nHash>0 );
822 pcache1EnterMutex(pCache->pGroup);
689 823
690 /* Step 1: Search the hash table for an existing entry. */ 824 /* Step 1: Search the hash table for an existing entry. */
691 if( pCache->nHash>0 ){ 825 pPage = pCache->apHash[iKey % pCache->nHash];
692 unsigned int h = iKey % pCache->nHash; 826 while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; }
693 for(pPage=pCache->apHash[h]; pPage&&pPage->iKey!=iKey; pPage=pPage->pNext);
694 }
695 827
696 /* Step 2: Abort if no existing page is found and createFlag is 0 */ 828 /* Step 2: Abort if no existing page is found and createFlag is 0 */
697 if( pPage || createFlag==0 ){ 829 if( pPage ){
698 pcache1PinPage(pPage); 830 if( !pPage->isPinned ) pcache1PinPage(pPage);
699 goto fetch_out; 831 }else if( createFlag ){
832 /* Steps 3, 4, and 5 implemented by this subroutine */
833 pPage = pcache1FetchStage2(pCache, iKey, createFlag);
700 } 834 }
701 835 assert( pPage==0 || pCache->iMaxKey>=iKey );
702 /* The pGroup local variable will normally be initialized by the 836 pcache1LeaveMutex(pCache->pGroup);
703 ** pcache1EnterMutex() macro above. But if SQLITE_MUTEX_OMIT is defined, 837 return (sqlite3_pcache_page*)pPage;
704 ** then pcache1EnterMutex() is a no-op, so we have to initialize the
705 ** local variable here. Delaying the initialization of pGroup is an
706 ** optimization: The common case is to exit the module before reaching
707 ** this point.
708 */
709 #ifdef SQLITE_MUTEX_OMIT
710 pGroup = pCache->pGroup;
711 #endif
712
713
714 /* Step 3: Abort if createFlag is 1 but the cache is nearly full */
715 nPinned = pCache->nPage - pCache->nRecyclable;
716 assert( nPinned>=0 );
717 assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
718 assert( pCache->n90pct == pCache->nMax*9/10 );
719 if( createFlag==1 && (
720 nPinned>=pGroup->mxPinned
721 || nPinned>=(int)pCache->n90pct
722 || pcache1UnderMemoryPressure(pCache)
723 )){
724 goto fetch_out;
725 }
726
727 if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){
728 goto fetch_out;
729 }
730
731 /* Step 4. Try to recycle a page. */
732 if( pCache->bPurgeable && pGroup->pLruTail && (
733 (pCache->nPage+1>=pCache->nMax)
734 || pGroup->nCurrentPage>=pGroup->nMaxPage
735 || pcache1UnderMemoryPressure(pCache)
736 )){
737 PCache1 *pOtherCache;
738 pPage = pGroup->pLruTail;
739 pcache1RemoveFromHash(pPage);
740 pcache1PinPage(pPage);
741 if( (pOtherCache = pPage->pCache)->szPage!=pCache->szPage ){
742 pcache1FreePage(pPage);
743 pPage = 0;
744 }else{
745 pGroup->nCurrentPage -=
746 (pOtherCache->bPurgeable - pCache->bPurgeable);
747 }
748 }
749
750 /* Step 5. If a usable page buffer has still not been found,
751 ** attempt to allocate a new one.
752 */
753 if( !pPage ){
754 if( createFlag==1 ) sqlite3BeginBenignMalloc();
755 pcache1LeaveMutex(pGroup);
756 pPage = pcache1AllocPage(pCache);
757 pcache1EnterMutex(pGroup);
758 if( createFlag==1 ) sqlite3EndBenignMalloc();
759 }
760
761 if( pPage ){
762 unsigned int h = iKey % pCache->nHash;
763 pCache->nPage++;
764 pPage->iKey = iKey;
765 pPage->pNext = pCache->apHash[h];
766 pPage->pCache = pCache;
767 pPage->pLruPrev = 0;
768 pPage->pLruNext = 0;
769 *(void **)(PGHDR1_TO_PAGE(pPage)) = 0;
770 pCache->apHash[h] = pPage;
771 }
772
773 fetch_out:
774 if( pPage && iKey>pCache->iMaxKey ){
775 pCache->iMaxKey = iKey;
776 }
777 pcache1LeaveMutex(pGroup);
778 return (pPage ? PGHDR1_TO_PAGE(pPage) : 0);
779 } 838 }
780 839
781 840
782 /* 841 /*
783 ** Implementation of the sqlite3_pcache.xUnpin method. 842 ** Implementation of the sqlite3_pcache.xUnpin method.
784 ** 843 **
785 ** Mark a page as unpinned (eligible for asynchronous recycling). 844 ** Mark a page as unpinned (eligible for asynchronous recycling).
786 */ 845 */
787 static void pcache1Unpin(sqlite3_pcache *p, void *pPg, int reuseUnlikely){ 846 static void pcache1Unpin(
847 sqlite3_pcache *p,
848 sqlite3_pcache_page *pPg,
849 int reuseUnlikely
850 ){
788 PCache1 *pCache = (PCache1 *)p; 851 PCache1 *pCache = (PCache1 *)p;
789 PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg); 852 PgHdr1 *pPage = (PgHdr1 *)pPg;
790 PGroup *pGroup = pCache->pGroup; 853 PGroup *pGroup = pCache->pGroup;
791 854
792 assert( pPage->pCache==pCache ); 855 assert( pPage->pCache==pCache );
793 pcache1EnterMutex(pGroup); 856 pcache1EnterMutex(pGroup);
794 857
795 /* It is an error to call this function if the page is already 858 /* It is an error to call this function if the page is already
796 ** part of the PGroup LRU list. 859 ** part of the PGroup LRU list.
797 */ 860 */
798 assert( pPage->pLruPrev==0 && pPage->pLruNext==0 ); 861 assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
799 assert( pGroup->pLruHead!=pPage && pGroup->pLruTail!=pPage ); 862 assert( pGroup->pLruHead!=pPage && pGroup->pLruTail!=pPage );
863 assert( pPage->isPinned==1 );
800 864
801 if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){ 865 if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){
802 pcache1RemoveFromHash(pPage); 866 pcache1RemoveFromHash(pPage);
803 pcache1FreePage(pPage); 867 pcache1FreePage(pPage);
804 }else{ 868 }else{
805 /* Add the page to the PGroup LRU list. */ 869 /* Add the page to the PGroup LRU list. */
806 if( pGroup->pLruHead ){ 870 if( pGroup->pLruHead ){
807 pGroup->pLruHead->pLruPrev = pPage; 871 pGroup->pLruHead->pLruPrev = pPage;
808 pPage->pLruNext = pGroup->pLruHead; 872 pPage->pLruNext = pGroup->pLruHead;
809 pGroup->pLruHead = pPage; 873 pGroup->pLruHead = pPage;
810 }else{ 874 }else{
811 pGroup->pLruTail = pPage; 875 pGroup->pLruTail = pPage;
812 pGroup->pLruHead = pPage; 876 pGroup->pLruHead = pPage;
813 } 877 }
814 pCache->nRecyclable++; 878 pCache->nRecyclable++;
879 pPage->isPinned = 0;
815 } 880 }
816 881
817 pcache1LeaveMutex(pCache->pGroup); 882 pcache1LeaveMutex(pCache->pGroup);
818 } 883 }
819 884
820 /* 885 /*
821 ** Implementation of the sqlite3_pcache.xRekey method. 886 ** Implementation of the sqlite3_pcache.xRekey method.
822 */ 887 */
823 static void pcache1Rekey( 888 static void pcache1Rekey(
824 sqlite3_pcache *p, 889 sqlite3_pcache *p,
825 void *pPg, 890 sqlite3_pcache_page *pPg,
826 unsigned int iOld, 891 unsigned int iOld,
827 unsigned int iNew 892 unsigned int iNew
828 ){ 893 ){
829 PCache1 *pCache = (PCache1 *)p; 894 PCache1 *pCache = (PCache1 *)p;
830 PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg); 895 PgHdr1 *pPage = (PgHdr1 *)pPg;
831 PgHdr1 **pp; 896 PgHdr1 **pp;
832 unsigned int h; 897 unsigned int h;
833 assert( pPage->iKey==iOld ); 898 assert( pPage->iKey==iOld );
834 assert( pPage->pCache==pCache ); 899 assert( pPage->pCache==pCache );
835 900
836 pcache1EnterMutex(pCache->pGroup); 901 pcache1EnterMutex(pCache->pGroup);
837 902
838 h = iOld%pCache->nHash; 903 h = iOld%pCache->nHash;
839 pp = &pCache->apHash[h]; 904 pp = &pCache->apHash[h];
840 while( (*pp)!=pPage ){ 905 while( (*pp)!=pPage ){
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 ** Implementation of the sqlite3_pcache.xDestroy method. 939 ** Implementation of the sqlite3_pcache.xDestroy method.
875 ** 940 **
876 ** Destroy a cache allocated using pcache1Create(). 941 ** Destroy a cache allocated using pcache1Create().
877 */ 942 */
878 static void pcache1Destroy(sqlite3_pcache *p){ 943 static void pcache1Destroy(sqlite3_pcache *p){
879 PCache1 *pCache = (PCache1 *)p; 944 PCache1 *pCache = (PCache1 *)p;
880 PGroup *pGroup = pCache->pGroup; 945 PGroup *pGroup = pCache->pGroup;
881 assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) ); 946 assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) );
882 pcache1EnterMutex(pGroup); 947 pcache1EnterMutex(pGroup);
883 pcache1TruncateUnsafe(pCache, 0); 948 pcache1TruncateUnsafe(pCache, 0);
949 assert( pGroup->nMaxPage >= pCache->nMax );
884 pGroup->nMaxPage -= pCache->nMax; 950 pGroup->nMaxPage -= pCache->nMax;
951 assert( pGroup->nMinPage >= pCache->nMin );
885 pGroup->nMinPage -= pCache->nMin; 952 pGroup->nMinPage -= pCache->nMin;
886 pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; 953 pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
887 pcache1EnforceMaxPage(pGroup); 954 pcache1EnforceMaxPage(pGroup);
888 pcache1LeaveMutex(pGroup); 955 pcache1LeaveMutex(pGroup);
889 sqlite3_free(pCache->apHash); 956 sqlite3_free(pCache->apHash);
890 sqlite3_free(pCache); 957 sqlite3_free(pCache);
891 } 958 }
892 959
893 /* 960 /*
894 ** This function is called during initialization (sqlite3_initialize()) to 961 ** This function is called during initialization (sqlite3_initialize()) to
895 ** install the default pluggable cache module, assuming the user has not 962 ** install the default pluggable cache module, assuming the user has not
896 ** already provided an alternative. 963 ** already provided an alternative.
897 */ 964 */
898 void sqlite3PCacheSetDefault(void){ 965 void sqlite3PCacheSetDefault(void){
899 static const sqlite3_pcache_methods defaultMethods = { 966 static const sqlite3_pcache_methods2 defaultMethods = {
967 1, /* iVersion */
900 0, /* pArg */ 968 0, /* pArg */
901 pcache1Init, /* xInit */ 969 pcache1Init, /* xInit */
902 pcache1Shutdown, /* xShutdown */ 970 pcache1Shutdown, /* xShutdown */
903 pcache1Create, /* xCreate */ 971 pcache1Create, /* xCreate */
904 pcache1Cachesize, /* xCachesize */ 972 pcache1Cachesize, /* xCachesize */
905 pcache1Pagecount, /* xPagecount */ 973 pcache1Pagecount, /* xPagecount */
906 pcache1Fetch, /* xFetch */ 974 pcache1Fetch, /* xFetch */
907 pcache1Unpin, /* xUnpin */ 975 pcache1Unpin, /* xUnpin */
908 pcache1Rekey, /* xRekey */ 976 pcache1Rekey, /* xRekey */
909 pcache1Truncate, /* xTruncate */ 977 pcache1Truncate, /* xTruncate */
910 pcache1Destroy /* xDestroy */ 978 pcache1Destroy, /* xDestroy */
979 pcache1Shrink /* xShrink */
911 }; 980 };
912 sqlite3_config(SQLITE_CONFIG_PCACHE, &defaultMethods); 981 sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods);
913 } 982 }
914 983
915 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT 984 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
916 /* 985 /*
917 ** This function is called to free superfluous dynamically allocated memory 986 ** This function is called to free superfluous dynamically allocated memory
918 ** held by the pager system. Memory in use by any SQLite pager allocated 987 ** held by the pager system. Memory in use by any SQLite pager allocated
919 ** by the current thread may be sqlite3_free()ed. 988 ** by the current thread may be sqlite3_free()ed.
920 ** 989 **
921 ** nReq is the number of bytes of memory required. Once this much has 990 ** nReq is the number of bytes of memory required. Once this much has
922 ** been released, the function returns. The return value is the total number 991 ** been released, the function returns. The return value is the total number
923 ** of bytes of memory released. 992 ** of bytes of memory released.
924 */ 993 */
925 int sqlite3PcacheReleaseMemory(int nReq){ 994 int sqlite3PcacheReleaseMemory(int nReq){
926 int nFree = 0; 995 int nFree = 0;
927 assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); 996 assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
928 assert( sqlite3_mutex_notheld(pcache1.mutex) ); 997 assert( sqlite3_mutex_notheld(pcache1.mutex) );
929 if( pcache1.pStart==0 ){ 998 if( pcache1.pStart==0 ){
930 PgHdr1 *p; 999 PgHdr1 *p;
931 pcache1EnterMutex(&pcache1.grp); 1000 pcache1EnterMutex(&pcache1.grp);
932 while( (nReq<0 || nFree<nReq) && ((p=pcache1.grp.pLruTail)!=0) ){ 1001 while( (nReq<0 || nFree<nReq) && ((p=pcache1.grp.pLruTail)!=0) ){
933 nFree += pcache1MemSize(PGHDR1_TO_PAGE(p)); 1002 nFree += pcache1MemSize(p->page.pBuf);
1003 #ifdef SQLITE_PCACHE_SEPARATE_HEADER
1004 nFree += sqlite3MemSize(p);
1005 #endif
1006 assert( p->isPinned==0 );
934 pcache1PinPage(p); 1007 pcache1PinPage(p);
935 pcache1RemoveFromHash(p); 1008 pcache1RemoveFromHash(p);
936 pcache1FreePage(p); 1009 pcache1FreePage(p);
937 } 1010 }
938 pcache1LeaveMutex(&pcache1.grp); 1011 pcache1LeaveMutex(&pcache1.grp);
939 } 1012 }
940 return nFree; 1013 return nFree;
941 } 1014 }
942 #endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */ 1015 #endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
943 1016
944 #ifdef SQLITE_TEST 1017 #ifdef SQLITE_TEST
945 /* 1018 /*
946 ** This function is used by test procedures to inspect the internal state 1019 ** This function is used by test procedures to inspect the internal state
947 ** of the global cache. 1020 ** of the global cache.
948 */ 1021 */
949 void sqlite3PcacheStats( 1022 void sqlite3PcacheStats(
950 int *pnCurrent, /* OUT: Total number of pages cached */ 1023 int *pnCurrent, /* OUT: Total number of pages cached */
951 int *pnMax, /* OUT: Global maximum cache size */ 1024 int *pnMax, /* OUT: Global maximum cache size */
952 int *pnMin, /* OUT: Sum of PCache1.nMin for purgeable caches */ 1025 int *pnMin, /* OUT: Sum of PCache1.nMin for purgeable caches */
953 int *pnRecyclable /* OUT: Total number of pages available for recycling */ 1026 int *pnRecyclable /* OUT: Total number of pages available for recycling */
954 ){ 1027 ){
955 PgHdr1 *p; 1028 PgHdr1 *p;
956 int nRecyclable = 0; 1029 int nRecyclable = 0;
957 for(p=pcache1.grp.pLruHead; p; p=p->pLruNext){ 1030 for(p=pcache1.grp.pLruHead; p; p=p->pLruNext){
1031 assert( p->isPinned==0 );
958 nRecyclable++; 1032 nRecyclable++;
959 } 1033 }
960 *pnCurrent = pcache1.grp.nCurrentPage; 1034 *pnCurrent = pcache1.grp.nCurrentPage;
961 *pnMax = pcache1.grp.nMaxPage; 1035 *pnMax = (int)pcache1.grp.nMaxPage;
962 *pnMin = pcache1.grp.nMinPage; 1036 *pnMin = (int)pcache1.grp.nMinPage;
963 *pnRecyclable = nRecyclable; 1037 *pnRecyclable = nRecyclable;
964 } 1038 }
965 #endif 1039 #endif
OLDNEW
« no previous file with comments | « third_party/sqlite/sqlite-src-3080704/src/pcache.c ('k') | third_party/sqlite/sqlite-src-3080704/src/pragma.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698