| OLD | NEW |
| 1 /* | 1 /* |
| 2 ** 2008 November 18 | 2 ** 2008 November 18 |
| 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 ** |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 */ | 93 */ |
| 94 #define TESTPCACHE_VALID 0x364585fd | 94 #define TESTPCACHE_VALID 0x364585fd |
| 95 #define TESTPCACHE_CLEAR 0xd42670d4 | 95 #define TESTPCACHE_CLEAR 0xd42670d4 |
| 96 | 96 |
| 97 /* | 97 /* |
| 98 ** Private implementation of a page cache. | 98 ** Private implementation of a page cache. |
| 99 */ | 99 */ |
| 100 typedef struct testpcache testpcache; | 100 typedef struct testpcache testpcache; |
| 101 struct testpcache { | 101 struct testpcache { |
| 102 int szPage; /* Size of each page. Multiple of 8. */ | 102 int szPage; /* Size of each page. Multiple of 8. */ |
| 103 int szExtra; /* Size of extra data that accompanies each page */ |
| 103 int bPurgeable; /* True if the page cache is purgeable */ | 104 int bPurgeable; /* True if the page cache is purgeable */ |
| 104 int nFree; /* Number of unused slots in a[] */ | 105 int nFree; /* Number of unused slots in a[] */ |
| 105 int nPinned; /* Number of pinned slots in a[] */ | 106 int nPinned; /* Number of pinned slots in a[] */ |
| 106 unsigned iRand; /* State of the PRNG */ | 107 unsigned iRand; /* State of the PRNG */ |
| 107 unsigned iMagic; /* Magic number for sanity checking */ | 108 unsigned iMagic; /* Magic number for sanity checking */ |
| 108 struct testpcachePage { | 109 struct testpcachePage { |
| 110 sqlite3_pcache_page page; /* Base class */ |
| 109 unsigned key; /* The key for this page. 0 means unallocated */ | 111 unsigned key; /* The key for this page. 0 means unallocated */ |
| 110 int isPinned; /* True if the page is pinned */ | 112 int isPinned; /* True if the page is pinned */ |
| 111 void *pData; /* Data for this page */ | |
| 112 } a[TESTPCACHE_NPAGE]; /* All pages in the cache */ | 113 } a[TESTPCACHE_NPAGE]; /* All pages in the cache */ |
| 113 }; | 114 }; |
| 114 | 115 |
| 115 /* | 116 /* |
| 116 ** Get a random number using the PRNG in the given page cache. | 117 ** Get a random number using the PRNG in the given page cache. |
| 117 */ | 118 */ |
| 118 static unsigned testpcacheRandom(testpcache *p){ | 119 static unsigned testpcacheRandom(testpcache *p){ |
| 119 unsigned x = 0; | 120 unsigned x = 0; |
| 120 int i; | 121 int i; |
| 121 for(i=0; i<4; i++){ | 122 for(i=0; i<4; i++){ |
| 122 p->iRand = (p->iRand*69069 + 5); | 123 p->iRand = (p->iRand*69069 + 5); |
| 123 x = (x<<8) | ((p->iRand>>16)&0xff); | 124 x = (x<<8) | ((p->iRand>>16)&0xff); |
| 124 } | 125 } |
| 125 return x; | 126 return x; |
| 126 } | 127 } |
| 127 | 128 |
| 128 | 129 |
| 129 /* | 130 /* |
| 130 ** Allocate a new page cache instance. | 131 ** Allocate a new page cache instance. |
| 131 */ | 132 */ |
| 132 static sqlite3_pcache *testpcacheCreate(int szPage, int bPurgeable){ | 133 static sqlite3_pcache *testpcacheCreate( |
| 134 int szPage, |
| 135 int szExtra, |
| 136 int bPurgeable |
| 137 ){ |
| 133 int nMem; | 138 int nMem; |
| 134 char *x; | 139 char *x; |
| 135 testpcache *p; | 140 testpcache *p; |
| 136 int i; | 141 int i; |
| 137 assert( testpcacheGlobal.pDummy!=0 ); | 142 assert( testpcacheGlobal.pDummy!=0 ); |
| 138 szPage = (szPage+7)&~7; | 143 szPage = (szPage+7)&~7; |
| 139 nMem = sizeof(testpcache) + TESTPCACHE_NPAGE*szPage; | 144 nMem = sizeof(testpcache) + TESTPCACHE_NPAGE*(szPage+szExtra); |
| 140 p = sqlite3_malloc( nMem ); | 145 p = sqlite3_malloc( nMem ); |
| 141 if( p==0 ) return 0; | 146 if( p==0 ) return 0; |
| 142 x = (char*)&p[1]; | 147 x = (char*)&p[1]; |
| 143 p->szPage = szPage; | 148 p->szPage = szPage; |
| 149 p->szExtra = szExtra; |
| 144 p->nFree = TESTPCACHE_NPAGE; | 150 p->nFree = TESTPCACHE_NPAGE; |
| 145 p->nPinned = 0; | 151 p->nPinned = 0; |
| 146 p->iRand = testpcacheGlobal.prngSeed; | 152 p->iRand = testpcacheGlobal.prngSeed; |
| 147 p->bPurgeable = bPurgeable; | 153 p->bPurgeable = bPurgeable; |
| 148 p->iMagic = TESTPCACHE_VALID; | 154 p->iMagic = TESTPCACHE_VALID; |
| 149 for(i=0; i<TESTPCACHE_NPAGE; i++, x += szPage){ | 155 for(i=0; i<TESTPCACHE_NPAGE; i++, x += (szPage+szExtra)){ |
| 150 p->a[i].key = 0; | 156 p->a[i].key = 0; |
| 151 p->a[i].isPinned = 0; | 157 p->a[i].isPinned = 0; |
| 152 p->a[i].pData = (void*)x; | 158 p->a[i].page.pBuf = (void*)x; |
| 159 p->a[i].page.pExtra = (void*)&x[szPage]; |
| 153 } | 160 } |
| 154 testpcacheGlobal.nInstance++; | 161 testpcacheGlobal.nInstance++; |
| 155 return (sqlite3_pcache*)p; | 162 return (sqlite3_pcache*)p; |
| 156 } | 163 } |
| 157 | 164 |
| 158 /* | 165 /* |
| 159 ** Set the cache size | 166 ** Set the cache size |
| 160 */ | 167 */ |
| 161 static void testpcacheCachesize(sqlite3_pcache *pCache, int newSize){ | 168 static void testpcacheCachesize(sqlite3_pcache *pCache, int newSize){ |
| 162 testpcache *p = (testpcache*)pCache; | 169 testpcache *p = (testpcache*)pCache; |
| 163 assert( p->iMagic==TESTPCACHE_VALID ); | 170 assert( p->iMagic==TESTPCACHE_VALID ); |
| 164 assert( newSize>=1 ); | |
| 165 assert( testpcacheGlobal.pDummy!=0 ); | 171 assert( testpcacheGlobal.pDummy!=0 ); |
| 166 assert( testpcacheGlobal.nInstance>0 ); | 172 assert( testpcacheGlobal.nInstance>0 ); |
| 167 } | 173 } |
| 168 | 174 |
| 169 /* | 175 /* |
| 170 ** Return the number of pages in the cache that are being used. | 176 ** Return the number of pages in the cache that are being used. |
| 171 ** This includes both pinned and unpinned pages. | 177 ** This includes both pinned and unpinned pages. |
| 172 */ | 178 */ |
| 173 static int testpcachePagecount(sqlite3_pcache *pCache){ | 179 static int testpcachePagecount(sqlite3_pcache *pCache){ |
| 174 testpcache *p = (testpcache*)pCache; | 180 testpcache *p = (testpcache*)pCache; |
| 175 assert( p->iMagic==TESTPCACHE_VALID ); | 181 assert( p->iMagic==TESTPCACHE_VALID ); |
| 176 assert( testpcacheGlobal.pDummy!=0 ); | 182 assert( testpcacheGlobal.pDummy!=0 ); |
| 177 assert( testpcacheGlobal.nInstance>0 ); | 183 assert( testpcacheGlobal.nInstance>0 ); |
| 178 return TESTPCACHE_NPAGE - p->nFree; | 184 return TESTPCACHE_NPAGE - p->nFree; |
| 179 } | 185 } |
| 180 | 186 |
| 181 /* | 187 /* |
| 182 ** Fetch a page. | 188 ** Fetch a page. |
| 183 */ | 189 */ |
| 184 static void *testpcacheFetch( | 190 static sqlite3_pcache_page *testpcacheFetch( |
| 185 sqlite3_pcache *pCache, | 191 sqlite3_pcache *pCache, |
| 186 unsigned key, | 192 unsigned key, |
| 187 int createFlag | 193 int createFlag |
| 188 ){ | 194 ){ |
| 189 testpcache *p = (testpcache*)pCache; | 195 testpcache *p = (testpcache*)pCache; |
| 190 int i, j; | 196 int i, j; |
| 191 assert( p->iMagic==TESTPCACHE_VALID ); | 197 assert( p->iMagic==TESTPCACHE_VALID ); |
| 192 assert( testpcacheGlobal.pDummy!=0 ); | 198 assert( testpcacheGlobal.pDummy!=0 ); |
| 193 assert( testpcacheGlobal.nInstance>0 ); | 199 assert( testpcacheGlobal.nInstance>0 ); |
| 194 | 200 |
| 195 /* See if the page is already in cache. Return immediately if it is */ | 201 /* See if the page is already in cache. Return immediately if it is */ |
| 196 for(i=0; i<TESTPCACHE_NPAGE; i++){ | 202 for(i=0; i<TESTPCACHE_NPAGE; i++){ |
| 197 if( p->a[i].key==key ){ | 203 if( p->a[i].key==key ){ |
| 198 if( !p->a[i].isPinned ){ | 204 if( !p->a[i].isPinned ){ |
| 199 p->nPinned++; | 205 p->nPinned++; |
| 200 assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree ); | 206 assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree ); |
| 201 p->a[i].isPinned = 1; | 207 p->a[i].isPinned = 1; |
| 202 } | 208 } |
| 203 return p->a[i].pData; | 209 return &p->a[i].page; |
| 204 } | 210 } |
| 205 } | 211 } |
| 206 | 212 |
| 207 /* If createFlag is 0, never allocate a new page */ | 213 /* If createFlag is 0, never allocate a new page */ |
| 208 if( createFlag==0 ){ | 214 if( createFlag==0 ){ |
| 209 return 0; | 215 return 0; |
| 210 } | 216 } |
| 211 | 217 |
| 212 /* If no pages are available, always fail */ | 218 /* If no pages are available, always fail */ |
| 213 if( p->nPinned==TESTPCACHE_NPAGE ){ | 219 if( p->nPinned==TESTPCACHE_NPAGE ){ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 230 | 236 |
| 231 /* Find a free page to allocate if there are any free pages. | 237 /* Find a free page to allocate if there are any free pages. |
| 232 ** Withhold TESTPCACHE_RESERVE free pages until createFlag is 2. | 238 ** Withhold TESTPCACHE_RESERVE free pages until createFlag is 2. |
| 233 */ | 239 */ |
| 234 if( p->nFree>TESTPCACHE_RESERVE || (createFlag==2 && p->nFree>0) ){ | 240 if( p->nFree>TESTPCACHE_RESERVE || (createFlag==2 && p->nFree>0) ){ |
| 235 j = testpcacheRandom(p) % TESTPCACHE_NPAGE; | 241 j = testpcacheRandom(p) % TESTPCACHE_NPAGE; |
| 236 for(i=0; i<TESTPCACHE_NPAGE; i++, j = (j+1)%TESTPCACHE_NPAGE){ | 242 for(i=0; i<TESTPCACHE_NPAGE; i++, j = (j+1)%TESTPCACHE_NPAGE){ |
| 237 if( p->a[j].key==0 ){ | 243 if( p->a[j].key==0 ){ |
| 238 p->a[j].key = key; | 244 p->a[j].key = key; |
| 239 p->a[j].isPinned = 1; | 245 p->a[j].isPinned = 1; |
| 240 memset(p->a[j].pData, 0, p->szPage); | 246 memset(p->a[j].page.pBuf, 0, p->szPage); |
| 247 memset(p->a[j].page.pExtra, 0, p->szExtra); |
| 241 p->nPinned++; | 248 p->nPinned++; |
| 242 p->nFree--; | 249 p->nFree--; |
| 243 assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree ); | 250 assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree ); |
| 244 return p->a[j].pData; | 251 return &p->a[j].page; |
| 245 } | 252 } |
| 246 } | 253 } |
| 247 | 254 |
| 248 /* The prior loop always finds a freepage to allocate */ | 255 /* The prior loop always finds a freepage to allocate */ |
| 249 assert( 0 ); | 256 assert( 0 ); |
| 250 } | 257 } |
| 251 | 258 |
| 252 /* If this cache is not purgeable then we have to fail. | 259 /* If this cache is not purgeable then we have to fail. |
| 253 */ | 260 */ |
| 254 if( p->bPurgeable==0 ){ | 261 if( p->bPurgeable==0 ){ |
| 255 return 0; | 262 return 0; |
| 256 } | 263 } |
| 257 | 264 |
| 258 /* If there are no free pages, recycle a page. The page to | 265 /* If there are no free pages, recycle a page. The page to |
| 259 ** recycle is selected at random from all unpinned pages. | 266 ** recycle is selected at random from all unpinned pages. |
| 260 */ | 267 */ |
| 261 j = testpcacheRandom(p) % TESTPCACHE_NPAGE; | 268 j = testpcacheRandom(p) % TESTPCACHE_NPAGE; |
| 262 for(i=0; i<TESTPCACHE_NPAGE; i++, j = (j+1)%TESTPCACHE_NPAGE){ | 269 for(i=0; i<TESTPCACHE_NPAGE; i++, j = (j+1)%TESTPCACHE_NPAGE){ |
| 263 if( p->a[j].key>0 && p->a[j].isPinned==0 ){ | 270 if( p->a[j].key>0 && p->a[j].isPinned==0 ){ |
| 264 p->a[j].key = key; | 271 p->a[j].key = key; |
| 265 p->a[j].isPinned = 1; | 272 p->a[j].isPinned = 1; |
| 266 memset(p->a[j].pData, 0, p->szPage); | 273 memset(p->a[j].page.pBuf, 0, p->szPage); |
| 274 memset(p->a[j].page.pExtra, 0, p->szExtra); |
| 267 p->nPinned++; | 275 p->nPinned++; |
| 268 assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree ); | 276 assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree ); |
| 269 return p->a[j].pData; | 277 return &p->a[j].page; |
| 270 } | 278 } |
| 271 } | 279 } |
| 272 | 280 |
| 273 /* The previous loop always finds a page to recycle. */ | 281 /* The previous loop always finds a page to recycle. */ |
| 274 assert(0); | 282 assert(0); |
| 275 return 0; | 283 return 0; |
| 276 } | 284 } |
| 277 | 285 |
| 278 /* | 286 /* |
| 279 ** Unpin a page. | 287 ** Unpin a page. |
| 280 */ | 288 */ |
| 281 static void testpcacheUnpin( | 289 static void testpcacheUnpin( |
| 282 sqlite3_pcache *pCache, | 290 sqlite3_pcache *pCache, |
| 283 void *pOldPage, | 291 sqlite3_pcache_page *pOldPage, |
| 284 int discard | 292 int discard |
| 285 ){ | 293 ){ |
| 286 testpcache *p = (testpcache*)pCache; | 294 testpcache *p = (testpcache*)pCache; |
| 287 int i; | 295 int i; |
| 288 assert( p->iMagic==TESTPCACHE_VALID ); | 296 assert( p->iMagic==TESTPCACHE_VALID ); |
| 289 assert( testpcacheGlobal.pDummy!=0 ); | 297 assert( testpcacheGlobal.pDummy!=0 ); |
| 290 assert( testpcacheGlobal.nInstance>0 ); | 298 assert( testpcacheGlobal.nInstance>0 ); |
| 291 | 299 |
| 292 /* Randomly discard pages as they are unpinned according to the | 300 /* Randomly discard pages as they are unpinned according to the |
| 293 ** discardChance setting. If discardChance is 0, the random discard | 301 ** discardChance setting. If discardChance is 0, the random discard |
| 294 ** never happens. If discardChance is 100, it always happens. | 302 ** never happens. If discardChance is 100, it always happens. |
| 295 */ | 303 */ |
| 296 if( p->bPurgeable | 304 if( p->bPurgeable |
| 297 && (100-testpcacheGlobal.discardChance) <= (testpcacheRandom(p)%100) | 305 && (100-testpcacheGlobal.discardChance) <= (testpcacheRandom(p)%100) |
| 298 ){ | 306 ){ |
| 299 discard = 1; | 307 discard = 1; |
| 300 } | 308 } |
| 301 | 309 |
| 302 for(i=0; i<TESTPCACHE_NPAGE; i++){ | 310 for(i=0; i<TESTPCACHE_NPAGE; i++){ |
| 303 if( p->a[i].pData==pOldPage ){ | 311 if( &p->a[i].page==pOldPage ){ |
| 304 /* The pOldPage pointer always points to a pinned page */ | 312 /* The pOldPage pointer always points to a pinned page */ |
| 305 assert( p->a[i].isPinned ); | 313 assert( p->a[i].isPinned ); |
| 306 p->a[i].isPinned = 0; | 314 p->a[i].isPinned = 0; |
| 307 p->nPinned--; | 315 p->nPinned--; |
| 308 assert( p->nPinned>=0 ); | 316 assert( p->nPinned>=0 ); |
| 309 if( discard ){ | 317 if( discard ){ |
| 310 p->a[i].key = 0; | 318 p->a[i].key = 0; |
| 311 p->nFree++; | 319 p->nFree++; |
| 312 assert( p->nFree<=TESTPCACHE_NPAGE ); | 320 assert( p->nFree<=TESTPCACHE_NPAGE ); |
| 313 } | 321 } |
| 314 return; | 322 return; |
| 315 } | 323 } |
| 316 } | 324 } |
| 317 | 325 |
| 318 /* The pOldPage pointer always points to a valid page */ | 326 /* The pOldPage pointer always points to a valid page */ |
| 319 assert( 0 ); | 327 assert( 0 ); |
| 320 } | 328 } |
| 321 | 329 |
| 322 | 330 |
| 323 /* | 331 /* |
| 324 ** Rekey a single page. | 332 ** Rekey a single page. |
| 325 */ | 333 */ |
| 326 static void testpcacheRekey( | 334 static void testpcacheRekey( |
| 327 sqlite3_pcache *pCache, | 335 sqlite3_pcache *pCache, |
| 328 void *pOldPage, | 336 sqlite3_pcache_page *pOldPage, |
| 329 unsigned oldKey, | 337 unsigned oldKey, |
| 330 unsigned newKey | 338 unsigned newKey |
| 331 ){ | 339 ){ |
| 332 testpcache *p = (testpcache*)pCache; | 340 testpcache *p = (testpcache*)pCache; |
| 333 int i; | 341 int i; |
| 334 assert( p->iMagic==TESTPCACHE_VALID ); | 342 assert( p->iMagic==TESTPCACHE_VALID ); |
| 335 assert( testpcacheGlobal.pDummy!=0 ); | 343 assert( testpcacheGlobal.pDummy!=0 ); |
| 336 assert( testpcacheGlobal.nInstance>0 ); | 344 assert( testpcacheGlobal.nInstance>0 ); |
| 337 | 345 |
| 338 /* If there already exists another page at newKey, verify that | 346 /* If there already exists another page at newKey, verify that |
| 339 ** the other page is unpinned and discard it. | 347 ** the other page is unpinned and discard it. |
| 340 */ | 348 */ |
| 341 for(i=0; i<TESTPCACHE_NPAGE; i++){ | 349 for(i=0; i<TESTPCACHE_NPAGE; i++){ |
| 342 if( p->a[i].key==newKey ){ | 350 if( p->a[i].key==newKey ){ |
| 343 /* The new key is never a page that is already pinned */ | 351 /* The new key is never a page that is already pinned */ |
| 344 assert( p->a[i].isPinned==0 ); | 352 assert( p->a[i].isPinned==0 ); |
| 345 p->a[i].key = 0; | 353 p->a[i].key = 0; |
| 346 p->nFree++; | 354 p->nFree++; |
| 347 assert( p->nFree<=TESTPCACHE_NPAGE ); | 355 assert( p->nFree<=TESTPCACHE_NPAGE ); |
| 348 break; | 356 break; |
| 349 } | 357 } |
| 350 } | 358 } |
| 351 | 359 |
| 352 /* Find the page to be rekeyed and rekey it. | 360 /* Find the page to be rekeyed and rekey it. |
| 353 */ | 361 */ |
| 354 for(i=0; i<TESTPCACHE_NPAGE; i++){ | 362 for(i=0; i<TESTPCACHE_NPAGE; i++){ |
| 355 if( p->a[i].key==oldKey ){ | 363 if( p->a[i].key==oldKey ){ |
| 356 /* The oldKey and pOldPage parameters match */ | 364 /* The oldKey and pOldPage parameters match */ |
| 357 assert( p->a[i].pData==pOldPage ); | 365 assert( &p->a[i].page==pOldPage ); |
| 358 /* Page to be rekeyed must be pinned */ | 366 /* Page to be rekeyed must be pinned */ |
| 359 assert( p->a[i].isPinned ); | 367 assert( p->a[i].isPinned ); |
| 360 p->a[i].key = newKey; | 368 p->a[i].key = newKey; |
| 361 return; | 369 return; |
| 362 } | 370 } |
| 363 } | 371 } |
| 364 | 372 |
| 365 /* Rekey is always given a valid page to work with */ | 373 /* Rekey is always given a valid page to work with */ |
| 366 assert( 0 ); | 374 assert( 0 ); |
| 367 } | 375 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 ** indicates the probability of discarding a page when unpinning the | 423 ** indicates the probability of discarding a page when unpinning the |
| 416 ** page. 0 means never discard (unless the discard flag is set). | 424 ** page. 0 means never discard (unless the discard flag is set). |
| 417 ** 100 means always discard. | 425 ** 100 means always discard. |
| 418 */ | 426 */ |
| 419 void installTestPCache( | 427 void installTestPCache( |
| 420 int installFlag, /* True to install. False to uninstall. */ | 428 int installFlag, /* True to install. False to uninstall. */ |
| 421 unsigned discardChance, /* 0-100. Chance to discard on unpin */ | 429 unsigned discardChance, /* 0-100. Chance to discard on unpin */ |
| 422 unsigned prngSeed, /* Seed for the PRNG */ | 430 unsigned prngSeed, /* Seed for the PRNG */ |
| 423 unsigned highStress /* Call xStress agressively */ | 431 unsigned highStress /* Call xStress agressively */ |
| 424 ){ | 432 ){ |
| 425 static const sqlite3_pcache_methods testPcache = { | 433 static const sqlite3_pcache_methods2 testPcache = { |
| 434 1, |
| 426 (void*)&testpcacheGlobal, | 435 (void*)&testpcacheGlobal, |
| 427 testpcacheInit, | 436 testpcacheInit, |
| 428 testpcacheShutdown, | 437 testpcacheShutdown, |
| 429 testpcacheCreate, | 438 testpcacheCreate, |
| 430 testpcacheCachesize, | 439 testpcacheCachesize, |
| 431 testpcachePagecount, | 440 testpcachePagecount, |
| 432 testpcacheFetch, | 441 testpcacheFetch, |
| 433 testpcacheUnpin, | 442 testpcacheUnpin, |
| 434 testpcacheRekey, | 443 testpcacheRekey, |
| 435 testpcacheTruncate, | 444 testpcacheTruncate, |
| 436 testpcacheDestroy, | 445 testpcacheDestroy, |
| 437 }; | 446 }; |
| 438 static sqlite3_pcache_methods defaultPcache; | 447 static sqlite3_pcache_methods2 defaultPcache; |
| 439 static int isInstalled = 0; | 448 static int isInstalled = 0; |
| 440 | 449 |
| 441 assert( testpcacheGlobal.nInstance==0 ); | 450 assert( testpcacheGlobal.nInstance==0 ); |
| 442 assert( testpcacheGlobal.pDummy==0 ); | 451 assert( testpcacheGlobal.pDummy==0 ); |
| 443 assert( discardChance<=100 ); | 452 assert( discardChance<=100 ); |
| 444 testpcacheGlobal.discardChance = discardChance; | 453 testpcacheGlobal.discardChance = discardChance; |
| 445 testpcacheGlobal.prngSeed = prngSeed ^ (prngSeed<<16); | 454 testpcacheGlobal.prngSeed = prngSeed ^ (prngSeed<<16); |
| 446 testpcacheGlobal.highStress = highStress; | 455 testpcacheGlobal.highStress = highStress; |
| 447 if( installFlag!=isInstalled ){ | 456 if( installFlag!=isInstalled ){ |
| 448 if( installFlag ){ | 457 if( installFlag ){ |
| 449 sqlite3_config(SQLITE_CONFIG_GETPCACHE, &defaultPcache); | 458 sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &defaultPcache); |
| 450 assert( defaultPcache.xCreate!=testpcacheCreate ); | 459 assert( defaultPcache.xCreate!=testpcacheCreate ); |
| 451 sqlite3_config(SQLITE_CONFIG_PCACHE, &testPcache); | 460 sqlite3_config(SQLITE_CONFIG_PCACHE2, &testPcache); |
| 452 }else{ | 461 }else{ |
| 453 assert( defaultPcache.xCreate!=0 ); | 462 assert( defaultPcache.xCreate!=0 ); |
| 454 sqlite3_config(SQLITE_CONFIG_PCACHE, &defaultPcache); | 463 sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultPcache); |
| 455 } | 464 } |
| 456 isInstalled = installFlag; | 465 isInstalled = installFlag; |
| 457 } | 466 } |
| 458 } | 467 } |
| OLD | NEW |