summaryrefslogtreecommitdiffstats
path: root/lib/libsqlite3/src/test_pcache.c
diff options
context:
space:
mode:
authorsthen <sthen@openbsd.org>2016-09-23 09:21:58 +0000
committersthen <sthen@openbsd.org>2016-09-23 09:21:58 +0000
commit25e4f8ab5acd0ef40feec6767a572bebbbe294b3 (patch)
tree20197c0e46bb6d260f4a310b6d5dd73b8d826f01 /lib/libsqlite3/src/test_pcache.c
parentremove usr.bin/sqlite3, it has moved back to ports (diff)
downloadwireguard-openbsd-25e4f8ab5acd0ef40feec6767a572bebbbe294b3.tar.xz
wireguard-openbsd-25e4f8ab5acd0ef40feec6767a572bebbbe294b3.zip
remove lib/libsqlite3, it has moved back to ports
Diffstat (limited to 'lib/libsqlite3/src/test_pcache.c')
-rw-r--r--lib/libsqlite3/src/test_pcache.c467
1 files changed, 0 insertions, 467 deletions
diff --git a/lib/libsqlite3/src/test_pcache.c b/lib/libsqlite3/src/test_pcache.c
deleted file mode 100644
index 8fcfe7e26e3..00000000000
--- a/lib/libsqlite3/src/test_pcache.c
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
-** 2008 November 18
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains code used for testing the SQLite system.
-** None of the code in this file goes into a deliverable build.
-**
-** This file contains an application-defined pager cache
-** implementation that can be plugged in in place of the
-** default pcache. This alternative pager cache will throw
-** some errors that the default cache does not.
-**
-** This pagecache implementation is designed for simplicity
-** not speed.
-*/
-#include "sqlite3.h"
-#include <string.h>
-#include <assert.h>
-
-/*
-** Global data used by this test implementation. There is no
-** mutexing, which means this page cache will not work in a
-** multi-threaded test.
-*/
-typedef struct testpcacheGlobalType testpcacheGlobalType;
-struct testpcacheGlobalType {
- void *pDummy; /* Dummy allocation to simulate failures */
- int nInstance; /* Number of current instances */
- unsigned discardChance; /* Chance of discarding on an unpin (0-100) */
- unsigned prngSeed; /* Seed for the PRNG */
- unsigned highStress; /* Call xStress agressively */
-};
-static testpcacheGlobalType testpcacheGlobal;
-
-/*
-** Initializer.
-**
-** Verify that the initializer is only called when the system is
-** uninitialized. Allocate some memory and report SQLITE_NOMEM if
-** the allocation fails. This provides a means to test the recovery
-** from a failed initialization attempt. It also verifies that the
-** the destructor always gets call - otherwise there would be a
-** memory leak.
-*/
-static int testpcacheInit(void *pArg){
- assert( pArg==(void*)&testpcacheGlobal );
- assert( testpcacheGlobal.pDummy==0 );
- assert( testpcacheGlobal.nInstance==0 );
- testpcacheGlobal.pDummy = sqlite3_malloc(10);
- return testpcacheGlobal.pDummy==0 ? SQLITE_NOMEM : SQLITE_OK;
-}
-
-/*
-** Destructor
-**
-** Verify that this is only called after initialization.
-** Free the memory allocated by the initializer.
-*/
-static void testpcacheShutdown(void *pArg){
- assert( pArg==(void*)&testpcacheGlobal );
- assert( testpcacheGlobal.pDummy!=0 );
- assert( testpcacheGlobal.nInstance==0 );
- sqlite3_free( testpcacheGlobal.pDummy );
- testpcacheGlobal.pDummy = 0;
-}
-
-/*
-** Number of pages in a cache.
-**
-** The number of pages is a hard upper bound in this test module.
-** If more pages are requested, sqlite3PcacheFetch() returns NULL.
-**
-** If testing with in-memory temp tables, provide a larger pcache.
-** Some of the test cases need this.
-*/
-#if defined(SQLITE_TEMP_STORE) && SQLITE_TEMP_STORE>=2
-# define TESTPCACHE_NPAGE 499
-#else
-# define TESTPCACHE_NPAGE 217
-#endif
-#define TESTPCACHE_RESERVE 17
-
-/*
-** Magic numbers used to determine validity of the page cache.
-*/
-#define TESTPCACHE_VALID 0x364585fd
-#define TESTPCACHE_CLEAR 0xd42670d4
-
-/*
-** Private implementation of a page cache.
-*/
-typedef struct testpcache testpcache;
-struct testpcache {
- int szPage; /* Size of each page. Multiple of 8. */
- int szExtra; /* Size of extra data that accompanies each page */
- int bPurgeable; /* True if the page cache is purgeable */
- int nFree; /* Number of unused slots in a[] */
- int nPinned; /* Number of pinned slots in a[] */
- unsigned iRand; /* State of the PRNG */
- unsigned iMagic; /* Magic number for sanity checking */
- struct testpcachePage {
- sqlite3_pcache_page page; /* Base class */
- unsigned key; /* The key for this page. 0 means unallocated */
- int isPinned; /* True if the page is pinned */
- } a[TESTPCACHE_NPAGE]; /* All pages in the cache */
-};
-
-/*
-** Get a random number using the PRNG in the given page cache.
-*/
-static unsigned testpcacheRandom(testpcache *p){
- unsigned x = 0;
- int i;
- for(i=0; i<4; i++){
- p->iRand = (p->iRand*69069 + 5);
- x = (x<<8) | ((p->iRand>>16)&0xff);
- }
- return x;
-}
-
-
-/*
-** Allocate a new page cache instance.
-*/
-static sqlite3_pcache *testpcacheCreate(
- int szPage,
- int szExtra,
- int bPurgeable
-){
- int nMem;
- char *x;
- testpcache *p;
- int i;
- assert( testpcacheGlobal.pDummy!=0 );
- szPage = (szPage+7)&~7;
- nMem = sizeof(testpcache) + TESTPCACHE_NPAGE*(szPage+szExtra);
- p = sqlite3_malloc( nMem );
- if( p==0 ) return 0;
- x = (char*)&p[1];
- p->szPage = szPage;
- p->szExtra = szExtra;
- p->nFree = TESTPCACHE_NPAGE;
- p->nPinned = 0;
- p->iRand = testpcacheGlobal.prngSeed;
- p->bPurgeable = bPurgeable;
- p->iMagic = TESTPCACHE_VALID;
- for(i=0; i<TESTPCACHE_NPAGE; i++, x += (szPage+szExtra)){
- p->a[i].key = 0;
- p->a[i].isPinned = 0;
- p->a[i].page.pBuf = (void*)x;
- p->a[i].page.pExtra = (void*)&x[szPage];
- }
- testpcacheGlobal.nInstance++;
- return (sqlite3_pcache*)p;
-}
-
-/*
-** Set the cache size
-*/
-static void testpcacheCachesize(sqlite3_pcache *pCache, int newSize){
- testpcache *p = (testpcache*)pCache;
- assert( p->iMagic==TESTPCACHE_VALID );
- assert( testpcacheGlobal.pDummy!=0 );
- assert( testpcacheGlobal.nInstance>0 );
-}
-
-/*
-** Return the number of pages in the cache that are being used.
-** This includes both pinned and unpinned pages.
-*/
-static int testpcachePagecount(sqlite3_pcache *pCache){
- testpcache *p = (testpcache*)pCache;
- assert( p->iMagic==TESTPCACHE_VALID );
- assert( testpcacheGlobal.pDummy!=0 );
- assert( testpcacheGlobal.nInstance>0 );
- return TESTPCACHE_NPAGE - p->nFree;
-}
-
-/*
-** Fetch a page.
-*/
-static sqlite3_pcache_page *testpcacheFetch(
- sqlite3_pcache *pCache,
- unsigned key,
- int createFlag
-){
- testpcache *p = (testpcache*)pCache;
- int i, j;
- assert( p->iMagic==TESTPCACHE_VALID );
- assert( testpcacheGlobal.pDummy!=0 );
- assert( testpcacheGlobal.nInstance>0 );
-
- /* See if the page is already in cache. Return immediately if it is */
- for(i=0; i<TESTPCACHE_NPAGE; i++){
- if( p->a[i].key==key ){
- if( !p->a[i].isPinned ){
- p->nPinned++;
- assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree );
- p->a[i].isPinned = 1;
- }
- return &p->a[i].page;
- }
- }
-
- /* If createFlag is 0, never allocate a new page */
- if( createFlag==0 ){
- return 0;
- }
-
- /* If no pages are available, always fail */
- if( p->nPinned==TESTPCACHE_NPAGE ){
- return 0;
- }
-
- /* Do not allocate the last TESTPCACHE_RESERVE pages unless createFlag is 2 */
- if( p->nPinned>=TESTPCACHE_NPAGE-TESTPCACHE_RESERVE && createFlag<2 ){
- return 0;
- }
-
- /* Do not allocate if highStress is enabled and createFlag is not 2.
- **
- ** The highStress setting causes pagerStress() to be called much more
- ** often, which exercises the pager logic more intensely.
- */
- if( testpcacheGlobal.highStress && createFlag<2 ){
- return 0;
- }
-
- /* Find a free page to allocate if there are any free pages.
- ** Withhold TESTPCACHE_RESERVE free pages until createFlag is 2.
- */
- if( p->nFree>TESTPCACHE_RESERVE || (createFlag==2 && p->nFree>0) ){
- j = testpcacheRandom(p) % TESTPCACHE_NPAGE;
- for(i=0; i<TESTPCACHE_NPAGE; i++, j = (j+1)%TESTPCACHE_NPAGE){
- if( p->a[j].key==0 ){
- p->a[j].key = key;
- p->a[j].isPinned = 1;
- memset(p->a[j].page.pBuf, 0, p->szPage);
- memset(p->a[j].page.pExtra, 0, p->szExtra);
- p->nPinned++;
- p->nFree--;
- assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree );
- return &p->a[j].page;
- }
- }
-
- /* The prior loop always finds a freepage to allocate */
- assert( 0 );
- }
-
- /* If this cache is not purgeable then we have to fail.
- */
- if( p->bPurgeable==0 ){
- return 0;
- }
-
- /* If there are no free pages, recycle a page. The page to
- ** recycle is selected at random from all unpinned pages.
- */
- j = testpcacheRandom(p) % TESTPCACHE_NPAGE;
- for(i=0; i<TESTPCACHE_NPAGE; i++, j = (j+1)%TESTPCACHE_NPAGE){
- if( p->a[j].key>0 && p->a[j].isPinned==0 ){
- p->a[j].key = key;
- p->a[j].isPinned = 1;
- memset(p->a[j].page.pBuf, 0, p->szPage);
- memset(p->a[j].page.pExtra, 0, p->szExtra);
- p->nPinned++;
- assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree );
- return &p->a[j].page;
- }
- }
-
- /* The previous loop always finds a page to recycle. */
- assert(0);
- return 0;
-}
-
-/*
-** Unpin a page.
-*/
-static void testpcacheUnpin(
- sqlite3_pcache *pCache,
- sqlite3_pcache_page *pOldPage,
- int discard
-){
- testpcache *p = (testpcache*)pCache;
- int i;
- assert( p->iMagic==TESTPCACHE_VALID );
- assert( testpcacheGlobal.pDummy!=0 );
- assert( testpcacheGlobal.nInstance>0 );
-
- /* Randomly discard pages as they are unpinned according to the
- ** discardChance setting. If discardChance is 0, the random discard
- ** never happens. If discardChance is 100, it always happens.
- */
- if( p->bPurgeable
- && (100-testpcacheGlobal.discardChance) <= (testpcacheRandom(p)%100)
- ){
- discard = 1;
- }
-
- for(i=0; i<TESTPCACHE_NPAGE; i++){
- if( &p->a[i].page==pOldPage ){
- /* The pOldPage pointer always points to a pinned page */
- assert( p->a[i].isPinned );
- p->a[i].isPinned = 0;
- p->nPinned--;
- assert( p->nPinned>=0 );
- if( discard ){
- p->a[i].key = 0;
- p->nFree++;
- assert( p->nFree<=TESTPCACHE_NPAGE );
- }
- return;
- }
- }
-
- /* The pOldPage pointer always points to a valid page */
- assert( 0 );
-}
-
-
-/*
-** Rekey a single page.
-*/
-static void testpcacheRekey(
- sqlite3_pcache *pCache,
- sqlite3_pcache_page *pOldPage,
- unsigned oldKey,
- unsigned newKey
-){
- testpcache *p = (testpcache*)pCache;
- int i;
- assert( p->iMagic==TESTPCACHE_VALID );
- assert( testpcacheGlobal.pDummy!=0 );
- assert( testpcacheGlobal.nInstance>0 );
-
- /* If there already exists another page at newKey, verify that
- ** the other page is unpinned and discard it.
- */
- for(i=0; i<TESTPCACHE_NPAGE; i++){
- if( p->a[i].key==newKey ){
- /* The new key is never a page that is already pinned */
- assert( p->a[i].isPinned==0 );
- p->a[i].key = 0;
- p->nFree++;
- assert( p->nFree<=TESTPCACHE_NPAGE );
- break;
- }
- }
-
- /* Find the page to be rekeyed and rekey it.
- */
- for(i=0; i<TESTPCACHE_NPAGE; i++){
- if( p->a[i].key==oldKey ){
- /* The oldKey and pOldPage parameters match */
- assert( &p->a[i].page==pOldPage );
- /* Page to be rekeyed must be pinned */
- assert( p->a[i].isPinned );
- p->a[i].key = newKey;
- return;
- }
- }
-
- /* Rekey is always given a valid page to work with */
- assert( 0 );
-}
-
-
-/*
-** Truncate the page cache. Every page with a key of iLimit or larger
-** is discarded.
-*/
-static void testpcacheTruncate(sqlite3_pcache *pCache, unsigned iLimit){
- testpcache *p = (testpcache*)pCache;
- unsigned int i;
- assert( p->iMagic==TESTPCACHE_VALID );
- assert( testpcacheGlobal.pDummy!=0 );
- assert( testpcacheGlobal.nInstance>0 );
- for(i=0; i<TESTPCACHE_NPAGE; i++){
- if( p->a[i].key>=iLimit ){
- p->a[i].key = 0;
- if( p->a[i].isPinned ){
- p->nPinned--;
- assert( p->nPinned>=0 );
- }
- p->nFree++;
- assert( p->nFree<=TESTPCACHE_NPAGE );
- }
- }
-}
-
-/*
-** Destroy a page cache.
-*/
-static void testpcacheDestroy(sqlite3_pcache *pCache){
- testpcache *p = (testpcache*)pCache;
- assert( p->iMagic==TESTPCACHE_VALID );
- assert( testpcacheGlobal.pDummy!=0 );
- assert( testpcacheGlobal.nInstance>0 );
- p->iMagic = TESTPCACHE_CLEAR;
- sqlite3_free(p);
- testpcacheGlobal.nInstance--;
-}
-
-
-/*
-** Invoke this routine to register or unregister the testing pager cache
-** implemented by this file.
-**
-** Install the test pager cache if installFlag is 1 and uninstall it if
-** installFlag is 0.
-**
-** When installing, discardChance is a number between 0 and 100 that
-** indicates the probability of discarding a page when unpinning the
-** page. 0 means never discard (unless the discard flag is set).
-** 100 means always discard.
-*/
-void installTestPCache(
- int installFlag, /* True to install. False to uninstall. */
- unsigned discardChance, /* 0-100. Chance to discard on unpin */
- unsigned prngSeed, /* Seed for the PRNG */
- unsigned highStress /* Call xStress agressively */
-){
- static const sqlite3_pcache_methods2 testPcache = {
- 1,
- (void*)&testpcacheGlobal,
- testpcacheInit,
- testpcacheShutdown,
- testpcacheCreate,
- testpcacheCachesize,
- testpcachePagecount,
- testpcacheFetch,
- testpcacheUnpin,
- testpcacheRekey,
- testpcacheTruncate,
- testpcacheDestroy,
- };
- static sqlite3_pcache_methods2 defaultPcache;
- static int isInstalled = 0;
-
- assert( testpcacheGlobal.nInstance==0 );
- assert( testpcacheGlobal.pDummy==0 );
- assert( discardChance<=100 );
- testpcacheGlobal.discardChance = discardChance;
- testpcacheGlobal.prngSeed = prngSeed ^ (prngSeed<<16);
- testpcacheGlobal.highStress = highStress;
- if( installFlag!=isInstalled ){
- if( installFlag ){
- sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &defaultPcache);
- assert( defaultPcache.xCreate!=testpcacheCreate );
- sqlite3_config(SQLITE_CONFIG_PCACHE2, &testPcache);
- }else{
- assert( defaultPcache.xCreate!=0 );
- sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultPcache);
- }
- isInstalled = installFlag;
- }
-}