mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-10 01:02:56 +03:00
Experimental change to the pcache interface to allow page buffers to be allocated separately from their associated container structures.
FossilOrigin-Name: c275c9d323cb1dccb031b199d413ac3a0b244fea
This commit is contained in:
35
manifest
35
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Make\sthe\sunix\sVFS\stolerant\sof\sread()\scalls\sthat\sreturn\sless\sthan\sthe\nrequested\snumber\sof\sbytes.
|
C Experimental\schange\sto\sthe\spcache\sinterface\sto\sallow\spage\sbuffers\sto\sbe\sallocated\sseparately\sfrom\stheir\sassociated\scontainer\sstructures.
|
||||||
D 2011-11-07T18:16:00.449
|
D 2011-11-08T20:08:44.098
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07
|
F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -138,7 +138,7 @@ F src/expr.c fbf116f90cabc917ae50bba24a73a0b55519a0c8
|
|||||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||||
F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5
|
F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5
|
||||||
F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9
|
F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9
|
||||||
F src/global.c e230227de13601714b29f9363028514aada5ae2f
|
F src/global.c 107ccaacb4b30895cf3a3a39decf417c804acfa1
|
||||||
F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af
|
F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af
|
||||||
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
|
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
|
||||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||||
@@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
|
|||||||
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
|
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
|
||||||
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
|
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
|
||||||
F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f
|
F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f
|
||||||
F src/main.c df06f5229b8046f85dde253dfd7fe35ae9e4902e
|
F src/main.c 93d49bc6abf4ccea97721d016b9f45228cff7057
|
||||||
F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9
|
F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9
|
||||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||||
F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206
|
F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206
|
||||||
@@ -171,9 +171,9 @@ F src/os_win.c 49d418916428a59d773f39993db0ecde56ab4c37
|
|||||||
F src/pager.c db33d4bf1e3e019c34c220971cc6c3aa07c30f54
|
F src/pager.c db33d4bf1e3e019c34c220971cc6c3aa07c30f54
|
||||||
F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d
|
F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d
|
||||||
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
|
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
|
||||||
F src/pcache.c 49e718c095810c6b3334e3a6d89970aceaddefce
|
F src/pcache.c fad8646667e074d06e29028029a0440d852497e5
|
||||||
F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
|
F src/pcache.h c770382f9fae4ca5025c5523bd0aa13cd6ddc6f8
|
||||||
F src/pcache1.c 24f5e85a78514584b46190260ba7ab0a66312197
|
F src/pcache1.c 54fc4ed623157b6f706da961c1d3776a40aa131d
|
||||||
F src/pragma.c da8ef96b3eec351e81e0061c39810e548bcc96d7
|
F src/pragma.c da8ef96b3eec351e81e0061c39810e548bcc96d7
|
||||||
F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4
|
F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4
|
||||||
F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869
|
F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869
|
||||||
@@ -182,9 +182,9 @@ F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809
|
|||||||
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
||||||
F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6
|
F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6
|
||||||
F src/shell.c 6d2ad7f80adc9c8c3195412879af36eb3196c1b6
|
F src/shell.c 6d2ad7f80adc9c8c3195412879af36eb3196c1b6
|
||||||
F src/sqlite.h.in b7a4e8d428e467d820cbb4c1d275fdda88b4d7ab
|
F src/sqlite.h.in c436f15dd27782e83d532651394c41fe4b96d1b0
|
||||||
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
|
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
|
||||||
F src/sqliteInt.h b0b6df8f7fe739e3cd718debb60f58853666d13e
|
F src/sqliteInt.h f87f241b9821a9d466c2711b7345d30ef3624249
|
||||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||||
F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a
|
F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a
|
||||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||||
@@ -208,7 +208,7 @@ F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
|
|||||||
F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5
|
F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5
|
||||||
F src/test_fuzzer.c f884f6f32e8513d34248d6e1ac8a32047fead254
|
F src/test_fuzzer.c f884f6f32e8513d34248d6e1ac8a32047fead254
|
||||||
F src/test_hexio.c c4773049603151704a6ab25ac5e936b5109caf5a
|
F src/test_hexio.c c4773049603151704a6ab25ac5e936b5109caf5a
|
||||||
F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c
|
F src/test_init.c 1ff3a696ca45e3c4cd7639217ded5d9c41428fed
|
||||||
F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99
|
F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99
|
||||||
F src/test_intarray.h 489edb9068bb926583445cb02589344961054207
|
F src/test_intarray.h 489edb9068bb926583445cb02589344961054207
|
||||||
F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff
|
F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff
|
||||||
@@ -219,7 +219,7 @@ F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d
|
|||||||
F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e
|
F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e
|
||||||
F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec
|
F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec
|
||||||
F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32
|
F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32
|
||||||
F src/test_pcache.c 7bf828972ac0d2403f5cfa4cd14da41f8ebe73d8
|
F src/test_pcache.c 708147942470815963efa7a58fe63470a1943a5e
|
||||||
F src/test_quota.c a391c866217e92986c6f523f05b08aa6956c8419
|
F src/test_quota.c a391c866217e92986c6f523f05b08aa6956c8419
|
||||||
F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1
|
F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1
|
||||||
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
|
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
|
||||||
@@ -592,7 +592,7 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
|
|||||||
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
|
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
|
||||||
F test/memdb.test 708a028d6d373e5b3842e4bdc8ba80998c9a4da6
|
F test/memdb.test 708a028d6d373e5b3842e4bdc8ba80998c9a4da6
|
||||||
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
|
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
|
||||||
F test/memsubsys1.test 16ce163ac1ace3d71bf0eaa6a821ed153addd91f
|
F test/memsubsys1.test c0db8a1e99f4fa07cb858900c55bad9547899aa8
|
||||||
F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9
|
F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9
|
||||||
F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d
|
F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d
|
||||||
F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0
|
F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0
|
||||||
@@ -974,7 +974,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
|
|||||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||||
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
|
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
|
||||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||||
P 4fe5b73115a8b44950767f1b528107261d7312c9
|
P a210695abcfa5cb04279edfd04824d881b7c4ada
|
||||||
R 235506ff1af96e54491bff797f85e25a
|
R 753cd5b3a540b0935d5201e586350091
|
||||||
U drh
|
T *branch * experimental-pcache
|
||||||
Z b43cdd5d2255740ef7ed4b6994dd0923
|
T *sym-experimental-pcache *
|
||||||
|
T -sym-trunk *
|
||||||
|
U dan
|
||||||
|
Z 65dd88e6b6c81cfeaddd0d87f1e89623
|
||||||
|
@@ -1 +1 @@
|
|||||||
a210695abcfa5cb04279edfd04824d881b7c4ada
|
c275c9d323cb1dccb031b199d413ac3a0b244fea
|
@@ -147,7 +147,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
|
|||||||
500, /* nLookaside */
|
500, /* nLookaside */
|
||||||
{0,0,0,0,0,0,0,0}, /* m */
|
{0,0,0,0,0,0,0,0}, /* m */
|
||||||
{0,0,0,0,0,0,0,0,0}, /* mutex */
|
{0,0,0,0,0,0,0,0,0}, /* mutex */
|
||||||
{0,0,0,0,0,0,0,0,0,0,0}, /* pcache */
|
{0,0,0,0,0,0,0,0,0,0,0}, /* pcache2 */
|
||||||
(void*)0, /* pHeap */
|
(void*)0, /* pHeap */
|
||||||
0, /* nHeap */
|
0, /* nHeap */
|
||||||
0, 0, /* mnHeap, mxHeap */
|
0, 0, /* mnHeap, mxHeap */
|
||||||
|
19
src/main.c
19
src/main.c
@@ -365,16 +365,25 @@ int sqlite3_config(int op, ...){
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SQLITE_CONFIG_PCACHE: {
|
case SQLITE_CONFIG_PCACHE: {
|
||||||
/* Specify an alternative page cache implementation */
|
/* no-op */
|
||||||
sqlite3GlobalConfig.pcache = *va_arg(ap, sqlite3_pcache_methods*);
|
break;
|
||||||
|
}
|
||||||
|
case SQLITE_CONFIG_GETPCACHE: {
|
||||||
|
/* now an error */
|
||||||
|
rc = SQLITE_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SQLITE_CONFIG_GETPCACHE: {
|
case SQLITE_CONFIG_PCACHE2: {
|
||||||
if( sqlite3GlobalConfig.pcache.xInit==0 ){
|
/* Specify an alternative page cache implementation */
|
||||||
|
sqlite3GlobalConfig.pcache2 = *va_arg(ap, sqlite3_pcache_methods2*);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SQLITE_CONFIG_GETPCACHE2: {
|
||||||
|
if( sqlite3GlobalConfig.pcache2.xInit==0 ){
|
||||||
sqlite3PCacheSetDefault();
|
sqlite3PCacheSetDefault();
|
||||||
}
|
}
|
||||||
*va_arg(ap, sqlite3_pcache_methods*) = sqlite3GlobalConfig.pcache;
|
*va_arg(ap, sqlite3_pcache_methods2*) = sqlite3GlobalConfig.pcache2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
76
src/pcache.c
76
src/pcache.c
@@ -131,7 +131,7 @@ static void pcacheUnpin(PgHdr *p){
|
|||||||
if( p->pgno==1 ){
|
if( p->pgno==1 ){
|
||||||
pCache->pPage1 = 0;
|
pCache->pPage1 = 0;
|
||||||
}
|
}
|
||||||
sqlite3GlobalConfig.pcache.xUnpin(pCache->pCache, p, 0);
|
sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,18 +141,18 @@ static void pcacheUnpin(PgHdr *p){
|
|||||||
** functions are threadsafe.
|
** functions are threadsafe.
|
||||||
*/
|
*/
|
||||||
int sqlite3PcacheInitialize(void){
|
int sqlite3PcacheInitialize(void){
|
||||||
if( sqlite3GlobalConfig.pcache.xInit==0 ){
|
if( sqlite3GlobalConfig.pcache2.xInit==0 ){
|
||||||
/* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the
|
/* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the
|
||||||
** built-in default page cache is used instead of the application defined
|
** built-in default page cache is used instead of the application defined
|
||||||
** page cache. */
|
** page cache. */
|
||||||
sqlite3PCacheSetDefault();
|
sqlite3PCacheSetDefault();
|
||||||
}
|
}
|
||||||
return sqlite3GlobalConfig.pcache.xInit(sqlite3GlobalConfig.pcache.pArg);
|
return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg);
|
||||||
}
|
}
|
||||||
void sqlite3PcacheShutdown(void){
|
void sqlite3PcacheShutdown(void){
|
||||||
if( sqlite3GlobalConfig.pcache.xShutdown ){
|
if( sqlite3GlobalConfig.pcache2.xShutdown ){
|
||||||
/* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */
|
/* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */
|
||||||
sqlite3GlobalConfig.pcache.xShutdown(sqlite3GlobalConfig.pcache.pArg);
|
sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ void sqlite3PcacheOpen(
|
|||||||
void sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
|
void sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
|
||||||
assert( pCache->nRef==0 && pCache->pDirty==0 );
|
assert( pCache->nRef==0 && pCache->pDirty==0 );
|
||||||
if( pCache->pCache ){
|
if( pCache->pCache ){
|
||||||
sqlite3GlobalConfig.pcache.xDestroy(pCache->pCache);
|
sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
|
||||||
pCache->pCache = 0;
|
pCache->pCache = 0;
|
||||||
pCache->pPage1 = 0;
|
pCache->pPage1 = 0;
|
||||||
}
|
}
|
||||||
@@ -207,7 +207,8 @@ int sqlite3PcacheFetch(
|
|||||||
int createFlag, /* If true, create page if it does not exist already */
|
int createFlag, /* If true, create page if it does not exist already */
|
||||||
PgHdr **ppPage /* Write the page here */
|
PgHdr **ppPage /* Write the page here */
|
||||||
){
|
){
|
||||||
PgHdr *pPage = 0;
|
sqlite3_pcache_page *pPage = 0;
|
||||||
|
PgHdr *pPgHdr = 0;
|
||||||
int eCreate;
|
int eCreate;
|
||||||
|
|
||||||
assert( pCache!=0 );
|
assert( pCache!=0 );
|
||||||
@@ -219,19 +220,19 @@ int sqlite3PcacheFetch(
|
|||||||
*/
|
*/
|
||||||
if( !pCache->pCache && createFlag ){
|
if( !pCache->pCache && createFlag ){
|
||||||
sqlite3_pcache *p;
|
sqlite3_pcache *p;
|
||||||
int nByte;
|
p = sqlite3GlobalConfig.pcache2.xCreate(
|
||||||
nByte = pCache->szPage + pCache->szExtra + sizeof(PgHdr);
|
pCache->szExtra + sizeof(PgHdr), pCache->szPage, pCache->bPurgeable
|
||||||
p = sqlite3GlobalConfig.pcache.xCreate(nByte, pCache->bPurgeable);
|
);
|
||||||
if( !p ){
|
if( !p ){
|
||||||
return SQLITE_NOMEM;
|
return SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
sqlite3GlobalConfig.pcache.xCachesize(p, pCache->nMax);
|
sqlite3GlobalConfig.pcache2.xCachesize(p, pCache->nMax);
|
||||||
pCache->pCache = p;
|
pCache->pCache = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
eCreate = createFlag * (1 + (!pCache->bPurgeable || !pCache->pDirty));
|
eCreate = createFlag * (1 + (!pCache->bPurgeable || !pCache->pDirty));
|
||||||
if( pCache->pCache ){
|
if( pCache->pCache ){
|
||||||
pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, eCreate);
|
pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !pPage && eCreate==1 ){
|
if( !pPage && eCreate==1 ){
|
||||||
@@ -266,33 +267,36 @@ int sqlite3PcacheFetch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, 2);
|
pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pPage ){
|
if( pPage ){
|
||||||
if( !pPage->pData ){
|
pPgHdr = (PgHdr *)pPage->pExtra;
|
||||||
memset(pPage, 0, sizeof(PgHdr));
|
|
||||||
pPage->pData = (void *)&pPage[1];
|
|
||||||
pPage->pExtra = (void*)&((char *)pPage->pData)[pCache->szPage];
|
|
||||||
memset(pPage->pExtra, 0, pCache->szExtra);
|
|
||||||
pPage->pCache = pCache;
|
|
||||||
pPage->pgno = pgno;
|
|
||||||
}
|
|
||||||
assert( pPage->pCache==pCache );
|
|
||||||
assert( pPage->pgno==pgno );
|
|
||||||
assert( pPage->pData==(void *)&pPage[1] );
|
|
||||||
assert( pPage->pExtra==(void *)&((char *)&pPage[1])[pCache->szPage] );
|
|
||||||
|
|
||||||
if( 0==pPage->nRef ){
|
if( !pPgHdr->pPage ){
|
||||||
|
memset(pPgHdr, 0, sizeof(PgHdr));
|
||||||
|
pPgHdr->pPage = pPage;
|
||||||
|
pPgHdr->pData = pPage->pBuf;
|
||||||
|
pPgHdr->pExtra = (void *)&pPgHdr[1];
|
||||||
|
memset(pPgHdr->pExtra, 0, pCache->szExtra);
|
||||||
|
pPgHdr->pCache = pCache;
|
||||||
|
pPgHdr->pgno = pgno;
|
||||||
|
}
|
||||||
|
assert( pPgHdr->pCache==pCache );
|
||||||
|
assert( pPgHdr->pgno==pgno );
|
||||||
|
assert( pPgHdr->pData==pPage->pBuf );
|
||||||
|
assert( pPgHdr->pExtra==(void *)&pPgHdr[1] );
|
||||||
|
|
||||||
|
if( 0==pPgHdr->nRef ){
|
||||||
pCache->nRef++;
|
pCache->nRef++;
|
||||||
}
|
}
|
||||||
pPage->nRef++;
|
pPgHdr->nRef++;
|
||||||
if( pgno==1 ){
|
if( pgno==1 ){
|
||||||
pCache->pPage1 = pPage;
|
pCache->pPage1 = pPgHdr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*ppPage = pPage;
|
*ppPage = pPgHdr;
|
||||||
return (pPage==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK;
|
return (pPgHdr==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -339,7 +343,7 @@ void sqlite3PcacheDrop(PgHdr *p){
|
|||||||
if( p->pgno==1 ){
|
if( p->pgno==1 ){
|
||||||
pCache->pPage1 = 0;
|
pCache->pPage1 = 0;
|
||||||
}
|
}
|
||||||
sqlite3GlobalConfig.pcache.xUnpin(pCache->pCache, p, 1);
|
sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -397,7 +401,7 @@ void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
|
|||||||
PCache *pCache = p->pCache;
|
PCache *pCache = p->pCache;
|
||||||
assert( p->nRef>0 );
|
assert( p->nRef>0 );
|
||||||
assert( newPgno>0 );
|
assert( newPgno>0 );
|
||||||
sqlite3GlobalConfig.pcache.xRekey(pCache->pCache, p, p->pgno, newPgno);
|
sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
|
||||||
p->pgno = newPgno;
|
p->pgno = newPgno;
|
||||||
if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
|
if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
|
||||||
pcacheRemoveFromDirtyList(p);
|
pcacheRemoveFromDirtyList(p);
|
||||||
@@ -434,7 +438,7 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
|
|||||||
memset(pCache->pPage1->pData, 0, pCache->szPage);
|
memset(pCache->pPage1->pData, 0, pCache->szPage);
|
||||||
pgno = 1;
|
pgno = 1;
|
||||||
}
|
}
|
||||||
sqlite3GlobalConfig.pcache.xTruncate(pCache->pCache, pgno+1);
|
sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,7 +447,7 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
|
|||||||
*/
|
*/
|
||||||
void sqlite3PcacheClose(PCache *pCache){
|
void sqlite3PcacheClose(PCache *pCache){
|
||||||
if( pCache->pCache ){
|
if( pCache->pCache ){
|
||||||
sqlite3GlobalConfig.pcache.xDestroy(pCache->pCache);
|
sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -555,7 +559,7 @@ int sqlite3PcachePageRefcount(PgHdr *p){
|
|||||||
int sqlite3PcachePagecount(PCache *pCache){
|
int sqlite3PcachePagecount(PCache *pCache){
|
||||||
int nPage = 0;
|
int nPage = 0;
|
||||||
if( pCache->pCache ){
|
if( pCache->pCache ){
|
||||||
nPage = sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache);
|
nPage = sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache);
|
||||||
}
|
}
|
||||||
return nPage;
|
return nPage;
|
||||||
}
|
}
|
||||||
@@ -575,7 +579,7 @@ int sqlite3PcacheGetCachesize(PCache *pCache){
|
|||||||
void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
|
void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
|
||||||
pCache->nMax = mxPage;
|
pCache->nMax = mxPage;
|
||||||
if( pCache->pCache ){
|
if( pCache->pCache ){
|
||||||
sqlite3GlobalConfig.pcache.xCachesize(pCache->pCache, mxPage);
|
sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, mxPage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -23,7 +23,8 @@ typedef struct PCache PCache;
|
|||||||
** structure.
|
** structure.
|
||||||
*/
|
*/
|
||||||
struct PgHdr {
|
struct PgHdr {
|
||||||
void *pData; /* Content of this page */
|
sqlite3_pcache_page *pPage; /* Pcache object page handle */
|
||||||
|
void *pData; /* Page data */
|
||||||
void *pExtra; /* Extra content */
|
void *pExtra; /* Extra content */
|
||||||
PgHdr *pDirty; /* Transient list of dirty pages */
|
PgHdr *pDirty; /* Transient list of dirty pages */
|
||||||
Pgno pgno; /* Page number for this page */
|
Pgno pgno; /* Page number for this page */
|
||||||
|
@@ -72,6 +72,7 @@ struct PCache1 {
|
|||||||
*/
|
*/
|
||||||
PGroup *pGroup; /* PGroup this cache belongs to */
|
PGroup *pGroup; /* PGroup this cache belongs to */
|
||||||
int szPage; /* Size of allocated pages in bytes */
|
int szPage; /* Size of allocated pages in bytes */
|
||||||
|
int szExtra; /* Size of extra space in bytes */
|
||||||
int bPurgeable; /* True if cache is purgeable */
|
int bPurgeable; /* True if cache is purgeable */
|
||||||
unsigned int nMin; /* Minimum number of pages reserved */
|
unsigned int nMin; /* Minimum number of pages reserved */
|
||||||
unsigned int nMax; /* Configured "cache_size" value */
|
unsigned int nMax; /* Configured "cache_size" value */
|
||||||
@@ -90,11 +91,12 @@ struct PCache1 {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** Each cache entry is represented by an instance of the following
|
** Each cache entry is represented by an instance of the following
|
||||||
** structure. A buffer of PgHdr1.pCache->szPage bytes is allocated
|
** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
|
||||||
** directly before this structure in memory (see the PGHDR1_TO_PAGE()
|
** PgHdr1.pCache->szPage bytes is allocated directly before this structure
|
||||||
** macro below).
|
** in memory.
|
||||||
*/
|
*/
|
||||||
struct PgHdr1 {
|
struct PgHdr1 {
|
||||||
|
sqlite3_pcache_page page;
|
||||||
unsigned int iKey; /* Key value (page number) */
|
unsigned int iKey; /* Key value (page number) */
|
||||||
PgHdr1 *pNext; /* Next in hash table chain */
|
PgHdr1 *pNext; /* Next in hash table chain */
|
||||||
PCache1 *pCache; /* Cache that currently owns this page */
|
PCache1 *pCache; /* Cache that currently owns this page */
|
||||||
@@ -144,21 +146,6 @@ static SQLITE_WSD struct PCacheGlobal {
|
|||||||
*/
|
*/
|
||||||
#define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g))
|
#define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g))
|
||||||
|
|
||||||
/*
|
|
||||||
** When a PgHdr1 structure is allocated, the associated PCache1.szPage
|
|
||||||
** bytes of data are located directly before it in memory (i.e. the total
|
|
||||||
** size of the allocation is sizeof(PgHdr1)+PCache1.szPage byte). The
|
|
||||||
** PGHDR1_TO_PAGE() macro takes a pointer to a PgHdr1 structure as
|
|
||||||
** an argument and returns a pointer to the associated block of szPage
|
|
||||||
** bytes. The PAGE_TO_PGHDR1() macro does the opposite: its argument is
|
|
||||||
** a pointer to a block of szPage bytes of data and the return value is
|
|
||||||
** a pointer to the associated PgHdr1 structure.
|
|
||||||
**
|
|
||||||
** assert( PGHDR1_TO_PAGE(PAGE_TO_PGHDR1(pCache, X))==X );
|
|
||||||
*/
|
|
||||||
#define PGHDR1_TO_PAGE(p) (void*)(((char*)p) - p->pCache->szPage)
|
|
||||||
#define PAGE_TO_PGHDR1(c, p) (PgHdr1*)(((char*)p) + c->szPage)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Macros to enter and leave the PCache LRU mutex.
|
** Macros to enter and leave the PCache LRU mutex.
|
||||||
*/
|
*/
|
||||||
@@ -288,7 +275,6 @@ static int pcache1MemSize(void *p){
|
|||||||
** Allocate a new page object initially associated with cache pCache.
|
** Allocate a new page object initially associated with cache pCache.
|
||||||
*/
|
*/
|
||||||
static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
|
static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
|
||||||
int nByte = sizeof(PgHdr1) + pCache->szPage;
|
|
||||||
PgHdr1 *p = 0;
|
PgHdr1 *p = 0;
|
||||||
void *pPg;
|
void *pPg;
|
||||||
|
|
||||||
@@ -297,16 +283,29 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
|
|||||||
** this mutex is not held. */
|
** this mutex is not held. */
|
||||||
assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
|
assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
|
||||||
pcache1LeaveMutex(pCache->pGroup);
|
pcache1LeaveMutex(pCache->pGroup);
|
||||||
pPg = pcache1Alloc(nByte);
|
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
|
||||||
|
pPg = pcache1Alloc(pCache->szPage);
|
||||||
|
p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
|
||||||
|
if( !pPg || !p ){
|
||||||
|
pcache1Free(pPg);
|
||||||
|
sqlite3_free(p);
|
||||||
|
pPg = 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
pPg = pcache1Alloc(sizeof(PgHdr1) + pCache->szPage + pCache->szExtra);
|
||||||
|
p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
|
||||||
|
#endif
|
||||||
pcache1EnterMutex(pCache->pGroup);
|
pcache1EnterMutex(pCache->pGroup);
|
||||||
|
|
||||||
if( pPg ){
|
if( pPg ){
|
||||||
p = PAGE_TO_PGHDR1(pCache, pPg);
|
p->page.pBuf = pPg;
|
||||||
|
p->page.pExtra = &p[1];
|
||||||
if( pCache->bPurgeable ){
|
if( pCache->bPurgeable ){
|
||||||
pCache->pGroup->nCurrentPage++;
|
pCache->pGroup->nCurrentPage++;
|
||||||
}
|
}
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
return p;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -320,7 +319,10 @@ static void pcache1FreePage(PgHdr1 *p){
|
|||||||
if( ALWAYS(p) ){
|
if( ALWAYS(p) ){
|
||||||
PCache1 *pCache = p->pCache;
|
PCache1 *pCache = p->pCache;
|
||||||
assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
|
assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
|
||||||
pcache1Free(PGHDR1_TO_PAGE(p));
|
pcache1Free(p->page.pBuf);
|
||||||
|
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
|
||||||
|
sqlite3_free(p);
|
||||||
|
#endif
|
||||||
if( pCache->bPurgeable ){
|
if( pCache->bPurgeable ){
|
||||||
pCache->pGroup->nCurrentPage--;
|
pCache->pGroup->nCurrentPage--;
|
||||||
}
|
}
|
||||||
@@ -361,7 +363,7 @@ void sqlite3PageFree(void *p){
|
|||||||
** the heap even further.
|
** the heap even further.
|
||||||
*/
|
*/
|
||||||
static int pcache1UnderMemoryPressure(PCache1 *pCache){
|
static int pcache1UnderMemoryPressure(PCache1 *pCache){
|
||||||
if( pcache1.nSlot && pCache->szPage<=pcache1.szSlot ){
|
if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){
|
||||||
return pcache1.bUnderPressure;
|
return pcache1.bUnderPressure;
|
||||||
}else{
|
}else{
|
||||||
return sqlite3HeapNearlyFull();
|
return sqlite3HeapNearlyFull();
|
||||||
@@ -552,7 +554,7 @@ static void pcache1Shutdown(void *NotUsed){
|
|||||||
**
|
**
|
||||||
** Allocate a new cache.
|
** Allocate a new cache.
|
||||||
*/
|
*/
|
||||||
static sqlite3_pcache *pcache1Create(int szPage, int bPurgeable){
|
static sqlite3_pcache *pcache1Create(int szExtra, int szPage, int bPurgeable){
|
||||||
PCache1 *pCache; /* The newly created page cache */
|
PCache1 *pCache; /* The newly created page cache */
|
||||||
PGroup *pGroup; /* The group the new page cache will belong to */
|
PGroup *pGroup; /* The group the new page cache will belong to */
|
||||||
int sz; /* Bytes of memory required to allocate the new cache */
|
int sz; /* Bytes of memory required to allocate the new cache */
|
||||||
@@ -587,6 +589,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int bPurgeable){
|
|||||||
}
|
}
|
||||||
pCache->pGroup = pGroup;
|
pCache->pGroup = pGroup;
|
||||||
pCache->szPage = szPage;
|
pCache->szPage = szPage;
|
||||||
|
pCache->szExtra = szExtra;
|
||||||
pCache->bPurgeable = (bPurgeable ? 1 : 0);
|
pCache->bPurgeable = (bPurgeable ? 1 : 0);
|
||||||
if( bPurgeable ){
|
if( bPurgeable ){
|
||||||
pCache->nMin = 10;
|
pCache->nMin = 10;
|
||||||
@@ -684,7 +687,11 @@ static int pcache1Pagecount(sqlite3_pcache *p){
|
|||||||
**
|
**
|
||||||
** 5. Otherwise, allocate and return a new page buffer.
|
** 5. Otherwise, allocate and return a new page buffer.
|
||||||
*/
|
*/
|
||||||
static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){
|
static sqlite3_pcache_page *pcache1Fetch(
|
||||||
|
sqlite3_pcache *p,
|
||||||
|
unsigned int iKey,
|
||||||
|
int createFlag
|
||||||
|
){
|
||||||
int nPinned;
|
int nPinned;
|
||||||
PCache1 *pCache = (PCache1 *)p;
|
PCache1 *pCache = (PCache1 *)p;
|
||||||
PGroup *pGroup;
|
PGroup *pGroup;
|
||||||
@@ -719,7 +726,6 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){
|
|||||||
pGroup = pCache->pGroup;
|
pGroup = pCache->pGroup;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Step 3: Abort if createFlag is 1 but the cache is nearly full */
|
/* Step 3: Abort if createFlag is 1 but the cache is nearly full */
|
||||||
nPinned = pCache->nPage - pCache->nRecyclable;
|
nPinned = pCache->nPage - pCache->nRecyclable;
|
||||||
assert( nPinned>=0 );
|
assert( nPinned>=0 );
|
||||||
@@ -747,12 +753,13 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){
|
|||||||
pPage = pGroup->pLruTail;
|
pPage = pGroup->pLruTail;
|
||||||
pcache1RemoveFromHash(pPage);
|
pcache1RemoveFromHash(pPage);
|
||||||
pcache1PinPage(pPage);
|
pcache1PinPage(pPage);
|
||||||
if( (pOtherCache = pPage->pCache)->szPage!=pCache->szPage ){
|
if( (pOtherCache = pPage->pCache)->szPage!=pCache->szPage
|
||||||
|
|| pOtherCache->szExtra!=pCache->szExtra
|
||||||
|
){
|
||||||
pcache1FreePage(pPage);
|
pcache1FreePage(pPage);
|
||||||
pPage = 0;
|
pPage = 0;
|
||||||
}else{
|
}else{
|
||||||
pGroup->nCurrentPage -=
|
pGroup->nCurrentPage -= (pOtherCache->bPurgeable - pCache->bPurgeable);
|
||||||
(pOtherCache->bPurgeable - pCache->bPurgeable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -773,7 +780,7 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){
|
|||||||
pPage->pCache = pCache;
|
pPage->pCache = pCache;
|
||||||
pPage->pLruPrev = 0;
|
pPage->pLruPrev = 0;
|
||||||
pPage->pLruNext = 0;
|
pPage->pLruNext = 0;
|
||||||
*(void **)(PGHDR1_TO_PAGE(pPage)) = 0;
|
*(void **)pPage->page.pExtra = 0;
|
||||||
pCache->apHash[h] = pPage;
|
pCache->apHash[h] = pPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -782,7 +789,7 @@ fetch_out:
|
|||||||
pCache->iMaxKey = iKey;
|
pCache->iMaxKey = iKey;
|
||||||
}
|
}
|
||||||
pcache1LeaveMutex(pGroup);
|
pcache1LeaveMutex(pGroup);
|
||||||
return (pPage ? PGHDR1_TO_PAGE(pPage) : 0);
|
return &pPage->page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -791,9 +798,13 @@ fetch_out:
|
|||||||
**
|
**
|
||||||
** Mark a page as unpinned (eligible for asynchronous recycling).
|
** Mark a page as unpinned (eligible for asynchronous recycling).
|
||||||
*/
|
*/
|
||||||
static void pcache1Unpin(sqlite3_pcache *p, void *pPg, int reuseUnlikely){
|
static void pcache1Unpin(
|
||||||
|
sqlite3_pcache *p,
|
||||||
|
sqlite3_pcache_page *pPg,
|
||||||
|
int reuseUnlikely
|
||||||
|
){
|
||||||
PCache1 *pCache = (PCache1 *)p;
|
PCache1 *pCache = (PCache1 *)p;
|
||||||
PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg);
|
PgHdr1 *pPage = (PgHdr1 *)pPg;
|
||||||
PGroup *pGroup = pCache->pGroup;
|
PGroup *pGroup = pCache->pGroup;
|
||||||
|
|
||||||
assert( pPage->pCache==pCache );
|
assert( pPage->pCache==pCache );
|
||||||
@@ -829,12 +840,12 @@ static void pcache1Unpin(sqlite3_pcache *p, void *pPg, int reuseUnlikely){
|
|||||||
*/
|
*/
|
||||||
static void pcache1Rekey(
|
static void pcache1Rekey(
|
||||||
sqlite3_pcache *p,
|
sqlite3_pcache *p,
|
||||||
void *pPg,
|
sqlite3_pcache_page *pPg,
|
||||||
unsigned int iOld,
|
unsigned int iOld,
|
||||||
unsigned int iNew
|
unsigned int iNew
|
||||||
){
|
){
|
||||||
PCache1 *pCache = (PCache1 *)p;
|
PCache1 *pCache = (PCache1 *)p;
|
||||||
PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg);
|
PgHdr1 *pPage = (PgHdr1 *)pPg;
|
||||||
PgHdr1 **pp;
|
PgHdr1 **pp;
|
||||||
unsigned int h;
|
unsigned int h;
|
||||||
assert( pPage->iKey==iOld );
|
assert( pPage->iKey==iOld );
|
||||||
@@ -903,7 +914,7 @@ static void pcache1Destroy(sqlite3_pcache *p){
|
|||||||
** already provided an alternative.
|
** already provided an alternative.
|
||||||
*/
|
*/
|
||||||
void sqlite3PCacheSetDefault(void){
|
void sqlite3PCacheSetDefault(void){
|
||||||
static const sqlite3_pcache_methods defaultMethods = {
|
static const sqlite3_pcache_methods2 defaultMethods = {
|
||||||
0, /* pArg */
|
0, /* pArg */
|
||||||
pcache1Init, /* xInit */
|
pcache1Init, /* xInit */
|
||||||
pcache1Shutdown, /* xShutdown */
|
pcache1Shutdown, /* xShutdown */
|
||||||
@@ -916,7 +927,7 @@ void sqlite3PCacheSetDefault(void){
|
|||||||
pcache1Truncate, /* xTruncate */
|
pcache1Truncate, /* xTruncate */
|
||||||
pcache1Destroy /* xDestroy */
|
pcache1Destroy /* xDestroy */
|
||||||
};
|
};
|
||||||
sqlite3_config(SQLITE_CONFIG_PCACHE, &defaultMethods);
|
sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||||
@@ -937,7 +948,10 @@ int sqlite3PcacheReleaseMemory(int nReq){
|
|||||||
PgHdr1 *p;
|
PgHdr1 *p;
|
||||||
pcache1EnterMutex(&pcache1.grp);
|
pcache1EnterMutex(&pcache1.grp);
|
||||||
while( (nReq<0 || nFree<nReq) && ((p=pcache1.grp.pLruTail)!=0) ){
|
while( (nReq<0 || nFree<nReq) && ((p=pcache1.grp.pLruTail)!=0) ){
|
||||||
nFree += pcache1MemSize(PGHDR1_TO_PAGE(p));
|
nFree += pcache1MemSize(p->page.pBuf);
|
||||||
|
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
|
||||||
|
nFree += sqlite3MemSize(p);
|
||||||
|
#endif
|
||||||
pcache1PinPage(p);
|
pcache1PinPage(p);
|
||||||
pcache1RemoveFromHash(p);
|
pcache1RemoveFromHash(p);
|
||||||
pcache1FreePage(p);
|
pcache1FreePage(p);
|
||||||
|
@@ -1497,6 +1497,8 @@ struct sqlite3_mem_methods {
|
|||||||
#define SQLITE_CONFIG_GETPCACHE 15 /* sqlite3_pcache_methods* */
|
#define SQLITE_CONFIG_GETPCACHE 15 /* sqlite3_pcache_methods* */
|
||||||
#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */
|
#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */
|
||||||
#define SQLITE_CONFIG_URI 17 /* int */
|
#define SQLITE_CONFIG_URI 17 /* int */
|
||||||
|
#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */
|
||||||
|
#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Database Connection Configuration Options
|
** CAPI3REF: Database Connection Configuration Options
|
||||||
@@ -6097,6 +6099,27 @@ struct sqlite3_pcache_methods {
|
|||||||
void (*xDestroy)(sqlite3_pcache*);
|
void (*xDestroy)(sqlite3_pcache*);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2;
|
||||||
|
typedef struct sqlite3_pcache_page sqlite3_pcache_page;
|
||||||
|
struct sqlite3_pcache_page {
|
||||||
|
void *pBuf;
|
||||||
|
void *pExtra;
|
||||||
|
};
|
||||||
|
struct sqlite3_pcache_methods2 {
|
||||||
|
void *pArg;
|
||||||
|
int (*xInit)(void*);
|
||||||
|
void (*xShutdown)(void*);
|
||||||
|
sqlite3_pcache *(*xCreate)(int szExtra, int szPage, int bPurgeable);
|
||||||
|
void (*xCachesize)(sqlite3_pcache*, int nCachesize);
|
||||||
|
int (*xPagecount)(sqlite3_pcache*);
|
||||||
|
sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
|
||||||
|
void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard);
|
||||||
|
void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*,
|
||||||
|
unsigned oldKey, unsigned newKey);
|
||||||
|
void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
|
||||||
|
void (*xDestroy)(sqlite3_pcache*);
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Online Backup Object
|
** CAPI3REF: Online Backup Object
|
||||||
**
|
**
|
||||||
|
@@ -2459,7 +2459,7 @@ struct Sqlite3Config {
|
|||||||
int nLookaside; /* Default lookaside buffer count */
|
int nLookaside; /* Default lookaside buffer count */
|
||||||
sqlite3_mem_methods m; /* Low-level memory allocation interface */
|
sqlite3_mem_methods m; /* Low-level memory allocation interface */
|
||||||
sqlite3_mutex_methods mutex; /* Low-level mutex interface */
|
sqlite3_mutex_methods mutex; /* Low-level mutex interface */
|
||||||
sqlite3_pcache_methods pcache; /* Low-level page-cache interface */
|
sqlite3_pcache_methods2 pcache2; /* Low-level page-cache interface */
|
||||||
void *pHeap; /* Heap storage space */
|
void *pHeap; /* Heap storage space */
|
||||||
int nHeap; /* Size of pHeap[] */
|
int nHeap; /* Size of pHeap[] */
|
||||||
int mnReq, mxReq; /* Min and max heap requests sizes */
|
int mnReq, mxReq; /* Min and max heap requests sizes */
|
||||||
|
@@ -30,9 +30,9 @@
|
|||||||
#include <tcl.h>
|
#include <tcl.h>
|
||||||
|
|
||||||
static struct Wrapped {
|
static struct Wrapped {
|
||||||
sqlite3_pcache_methods pcache;
|
sqlite3_pcache_methods2 pcache;
|
||||||
sqlite3_mem_methods mem;
|
sqlite3_mem_methods mem;
|
||||||
sqlite3_mutex_methods mutex;
|
sqlite3_mutex_methods mutex;
|
||||||
|
|
||||||
int mem_init; /* True if mem subsystem is initalized */
|
int mem_init; /* True if mem subsystem is initalized */
|
||||||
int mem_fail; /* True to fail mem subsystem inialization */
|
int mem_fail; /* True to fail mem subsystem inialization */
|
||||||
@@ -123,8 +123,8 @@ static void wrPCacheShutdown(void *pArg){
|
|||||||
wrapped.pcache_init = 0;
|
wrapped.pcache_init = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sqlite3_pcache *wrPCacheCreate(int a, int b){
|
static sqlite3_pcache *wrPCacheCreate(int a, int b, int c){
|
||||||
return wrapped.pcache.xCreate(a, b);
|
return wrapped.pcache.xCreate(a, b, c);
|
||||||
}
|
}
|
||||||
static void wrPCacheCachesize(sqlite3_pcache *p, int n){
|
static void wrPCacheCachesize(sqlite3_pcache *p, int n){
|
||||||
wrapped.pcache.xCachesize(p, n);
|
wrapped.pcache.xCachesize(p, n);
|
||||||
@@ -132,13 +132,18 @@ static void wrPCacheCachesize(sqlite3_pcache *p, int n){
|
|||||||
static int wrPCachePagecount(sqlite3_pcache *p){
|
static int wrPCachePagecount(sqlite3_pcache *p){
|
||||||
return wrapped.pcache.xPagecount(p);
|
return wrapped.pcache.xPagecount(p);
|
||||||
}
|
}
|
||||||
static void *wrPCacheFetch(sqlite3_pcache *p, unsigned a, int b){
|
static sqlite3_pcache_page *wrPCacheFetch(sqlite3_pcache *p, unsigned a, int b){
|
||||||
return wrapped.pcache.xFetch(p, a, b);
|
return wrapped.pcache.xFetch(p, a, b);
|
||||||
}
|
}
|
||||||
static void wrPCacheUnpin(sqlite3_pcache *p, void *a, int b){
|
static void wrPCacheUnpin(sqlite3_pcache *p, sqlite3_pcache_page *a, int b){
|
||||||
wrapped.pcache.xUnpin(p, a, b);
|
wrapped.pcache.xUnpin(p, a, b);
|
||||||
}
|
}
|
||||||
static void wrPCacheRekey(sqlite3_pcache *p, void *a, unsigned b, unsigned c){
|
static void wrPCacheRekey(
|
||||||
|
sqlite3_pcache *p,
|
||||||
|
sqlite3_pcache_page *a,
|
||||||
|
unsigned b,
|
||||||
|
unsigned c
|
||||||
|
){
|
||||||
wrapped.pcache.xRekey(p, a, b, c);
|
wrapped.pcache.xRekey(p, a, b, c);
|
||||||
}
|
}
|
||||||
static void wrPCacheTruncate(sqlite3_pcache *p, unsigned a){
|
static void wrPCacheTruncate(sqlite3_pcache *p, unsigned a){
|
||||||
@@ -154,7 +159,7 @@ static void installInitWrappers(void){
|
|||||||
wrMutexFree, wrMutexEnter, wrMutexTry,
|
wrMutexFree, wrMutexEnter, wrMutexTry,
|
||||||
wrMutexLeave, wrMutexHeld, wrMutexNotheld
|
wrMutexLeave, wrMutexHeld, wrMutexNotheld
|
||||||
};
|
};
|
||||||
sqlite3_pcache_methods pcachemethods = {
|
sqlite3_pcache_methods2 pcachemethods = {
|
||||||
0,
|
0,
|
||||||
wrPCacheInit, wrPCacheShutdown, wrPCacheCreate,
|
wrPCacheInit, wrPCacheShutdown, wrPCacheCreate,
|
||||||
wrPCacheCachesize, wrPCachePagecount, wrPCacheFetch,
|
wrPCacheCachesize, wrPCachePagecount, wrPCacheFetch,
|
||||||
@@ -173,10 +178,10 @@ static void installInitWrappers(void){
|
|||||||
sqlite3_shutdown();
|
sqlite3_shutdown();
|
||||||
sqlite3_config(SQLITE_CONFIG_GETMUTEX, &wrapped.mutex);
|
sqlite3_config(SQLITE_CONFIG_GETMUTEX, &wrapped.mutex);
|
||||||
sqlite3_config(SQLITE_CONFIG_GETMALLOC, &wrapped.mem);
|
sqlite3_config(SQLITE_CONFIG_GETMALLOC, &wrapped.mem);
|
||||||
sqlite3_config(SQLITE_CONFIG_GETPCACHE, &wrapped.pcache);
|
sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &wrapped.pcache);
|
||||||
sqlite3_config(SQLITE_CONFIG_MUTEX, &mutexmethods);
|
sqlite3_config(SQLITE_CONFIG_MUTEX, &mutexmethods);
|
||||||
sqlite3_config(SQLITE_CONFIG_MALLOC, &memmethods);
|
sqlite3_config(SQLITE_CONFIG_MALLOC, &memmethods);
|
||||||
sqlite3_config(SQLITE_CONFIG_PCACHE, &pcachemethods);
|
sqlite3_config(SQLITE_CONFIG_PCACHE2, &pcachemethods);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int init_wrapper_install(
|
static int init_wrapper_install(
|
||||||
@@ -218,7 +223,7 @@ static int init_wrapper_uninstall(
|
|||||||
sqlite3_shutdown();
|
sqlite3_shutdown();
|
||||||
sqlite3_config(SQLITE_CONFIG_MUTEX, &wrapped.mutex);
|
sqlite3_config(SQLITE_CONFIG_MUTEX, &wrapped.mutex);
|
||||||
sqlite3_config(SQLITE_CONFIG_MALLOC, &wrapped.mem);
|
sqlite3_config(SQLITE_CONFIG_MALLOC, &wrapped.mem);
|
||||||
sqlite3_config(SQLITE_CONFIG_PCACHE, &wrapped.pcache);
|
sqlite3_config(SQLITE_CONFIG_PCACHE2, &wrapped.pcache);
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -100,15 +100,16 @@ static void testpcacheShutdown(void *pArg){
|
|||||||
typedef struct testpcache testpcache;
|
typedef struct testpcache testpcache;
|
||||||
struct testpcache {
|
struct testpcache {
|
||||||
int szPage; /* Size of each page. Multiple of 8. */
|
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 bPurgeable; /* True if the page cache is purgeable */
|
||||||
int nFree; /* Number of unused slots in a[] */
|
int nFree; /* Number of unused slots in a[] */
|
||||||
int nPinned; /* Number of pinned slots in a[] */
|
int nPinned; /* Number of pinned slots in a[] */
|
||||||
unsigned iRand; /* State of the PRNG */
|
unsigned iRand; /* State of the PRNG */
|
||||||
unsigned iMagic; /* Magic number for sanity checking */
|
unsigned iMagic; /* Magic number for sanity checking */
|
||||||
struct testpcachePage {
|
struct testpcachePage {
|
||||||
|
sqlite3_pcache_page page; /* Base class */
|
||||||
unsigned key; /* The key for this page. 0 means unallocated */
|
unsigned key; /* The key for this page. 0 means unallocated */
|
||||||
int isPinned; /* True if the page is pinned */
|
int isPinned; /* True if the page is pinned */
|
||||||
void *pData; /* Data for this page */
|
|
||||||
} a[TESTPCACHE_NPAGE]; /* All pages in the cache */
|
} a[TESTPCACHE_NPAGE]; /* All pages in the cache */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -129,27 +130,33 @@ static unsigned testpcacheRandom(testpcache *p){
|
|||||||
/*
|
/*
|
||||||
** Allocate a new page cache instance.
|
** Allocate a new page cache instance.
|
||||||
*/
|
*/
|
||||||
static sqlite3_pcache *testpcacheCreate(int szPage, int bPurgeable){
|
static sqlite3_pcache *testpcacheCreate(
|
||||||
|
int szExtra,
|
||||||
|
int szPage,
|
||||||
|
int bPurgeable
|
||||||
|
){
|
||||||
int nMem;
|
int nMem;
|
||||||
char *x;
|
char *x;
|
||||||
testpcache *p;
|
testpcache *p;
|
||||||
int i;
|
int i;
|
||||||
assert( testpcacheGlobal.pDummy!=0 );
|
assert( testpcacheGlobal.pDummy!=0 );
|
||||||
szPage = (szPage+7)&~7;
|
szPage = (szPage+7)&~7;
|
||||||
nMem = sizeof(testpcache) + TESTPCACHE_NPAGE*szPage;
|
nMem = sizeof(testpcache) + TESTPCACHE_NPAGE*(szPage+szExtra);
|
||||||
p = sqlite3_malloc( nMem );
|
p = sqlite3_malloc( nMem );
|
||||||
if( p==0 ) return 0;
|
if( p==0 ) return 0;
|
||||||
x = (char*)&p[1];
|
x = (char*)&p[1];
|
||||||
p->szPage = szPage;
|
p->szPage = szPage;
|
||||||
|
p->szExtra = szExtra;
|
||||||
p->nFree = TESTPCACHE_NPAGE;
|
p->nFree = TESTPCACHE_NPAGE;
|
||||||
p->nPinned = 0;
|
p->nPinned = 0;
|
||||||
p->iRand = testpcacheGlobal.prngSeed;
|
p->iRand = testpcacheGlobal.prngSeed;
|
||||||
p->bPurgeable = bPurgeable;
|
p->bPurgeable = bPurgeable;
|
||||||
p->iMagic = TESTPCACHE_VALID;
|
p->iMagic = TESTPCACHE_VALID;
|
||||||
for(i=0; i<TESTPCACHE_NPAGE; i++, x += szPage){
|
for(i=0; i<TESTPCACHE_NPAGE; i++, x += (szPage+szExtra)){
|
||||||
p->a[i].key = 0;
|
p->a[i].key = 0;
|
||||||
p->a[i].isPinned = 0;
|
p->a[i].isPinned = 0;
|
||||||
p->a[i].pData = (void*)x;
|
p->a[i].page.pBuf = (void*)x;
|
||||||
|
p->a[i].page.pExtra = (void*)&x[szPage];
|
||||||
}
|
}
|
||||||
testpcacheGlobal.nInstance++;
|
testpcacheGlobal.nInstance++;
|
||||||
return (sqlite3_pcache*)p;
|
return (sqlite3_pcache*)p;
|
||||||
@@ -181,7 +188,7 @@ static int testpcachePagecount(sqlite3_pcache *pCache){
|
|||||||
/*
|
/*
|
||||||
** Fetch a page.
|
** Fetch a page.
|
||||||
*/
|
*/
|
||||||
static void *testpcacheFetch(
|
static sqlite3_pcache_page *testpcacheFetch(
|
||||||
sqlite3_pcache *pCache,
|
sqlite3_pcache *pCache,
|
||||||
unsigned key,
|
unsigned key,
|
||||||
int createFlag
|
int createFlag
|
||||||
@@ -200,7 +207,7 @@ static void *testpcacheFetch(
|
|||||||
assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree );
|
assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree );
|
||||||
p->a[i].isPinned = 1;
|
p->a[i].isPinned = 1;
|
||||||
}
|
}
|
||||||
return p->a[i].pData;
|
return &p->a[i].page;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,11 +244,12 @@ static void *testpcacheFetch(
|
|||||||
if( p->a[j].key==0 ){
|
if( p->a[j].key==0 ){
|
||||||
p->a[j].key = key;
|
p->a[j].key = key;
|
||||||
p->a[j].isPinned = 1;
|
p->a[j].isPinned = 1;
|
||||||
memset(p->a[j].pData, 0, p->szPage);
|
memset(p->a[j].page.pBuf, 0, p->szPage);
|
||||||
|
memset(p->a[j].page.pExtra, 0, p->szExtra);
|
||||||
p->nPinned++;
|
p->nPinned++;
|
||||||
p->nFree--;
|
p->nFree--;
|
||||||
assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree );
|
assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree );
|
||||||
return p->a[j].pData;
|
return &p->a[j].page;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,10 +271,11 @@ static void *testpcacheFetch(
|
|||||||
if( p->a[j].key>0 && p->a[j].isPinned==0 ){
|
if( p->a[j].key>0 && p->a[j].isPinned==0 ){
|
||||||
p->a[j].key = key;
|
p->a[j].key = key;
|
||||||
p->a[j].isPinned = 1;
|
p->a[j].isPinned = 1;
|
||||||
memset(p->a[j].pData, 0, p->szPage);
|
memset(p->a[j].page.pBuf, 0, p->szPage);
|
||||||
|
memset(p->a[j].page.pExtra, 0, p->szExtra);
|
||||||
p->nPinned++;
|
p->nPinned++;
|
||||||
assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree );
|
assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree );
|
||||||
return p->a[j].pData;
|
return &p->a[j].page;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +289,7 @@ static void *testpcacheFetch(
|
|||||||
*/
|
*/
|
||||||
static void testpcacheUnpin(
|
static void testpcacheUnpin(
|
||||||
sqlite3_pcache *pCache,
|
sqlite3_pcache *pCache,
|
||||||
void *pOldPage,
|
sqlite3_pcache_page *pOldPage,
|
||||||
int discard
|
int discard
|
||||||
){
|
){
|
||||||
testpcache *p = (testpcache*)pCache;
|
testpcache *p = (testpcache*)pCache;
|
||||||
@@ -300,7 +309,7 @@ static void testpcacheUnpin(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(i=0; i<TESTPCACHE_NPAGE; i++){
|
for(i=0; i<TESTPCACHE_NPAGE; i++){
|
||||||
if( p->a[i].pData==pOldPage ){
|
if( &p->a[i].page==pOldPage ){
|
||||||
/* The pOldPage pointer always points to a pinned page */
|
/* The pOldPage pointer always points to a pinned page */
|
||||||
assert( p->a[i].isPinned );
|
assert( p->a[i].isPinned );
|
||||||
p->a[i].isPinned = 0;
|
p->a[i].isPinned = 0;
|
||||||
@@ -325,7 +334,7 @@ static void testpcacheUnpin(
|
|||||||
*/
|
*/
|
||||||
static void testpcacheRekey(
|
static void testpcacheRekey(
|
||||||
sqlite3_pcache *pCache,
|
sqlite3_pcache *pCache,
|
||||||
void *pOldPage,
|
sqlite3_pcache_page *pOldPage,
|
||||||
unsigned oldKey,
|
unsigned oldKey,
|
||||||
unsigned newKey
|
unsigned newKey
|
||||||
){
|
){
|
||||||
@@ -354,7 +363,7 @@ static void testpcacheRekey(
|
|||||||
for(i=0; i<TESTPCACHE_NPAGE; i++){
|
for(i=0; i<TESTPCACHE_NPAGE; i++){
|
||||||
if( p->a[i].key==oldKey ){
|
if( p->a[i].key==oldKey ){
|
||||||
/* The oldKey and pOldPage parameters match */
|
/* The oldKey and pOldPage parameters match */
|
||||||
assert( p->a[i].pData==pOldPage );
|
assert( &p->a[i].page==pOldPage );
|
||||||
/* Page to be rekeyed must be pinned */
|
/* Page to be rekeyed must be pinned */
|
||||||
assert( p->a[i].isPinned );
|
assert( p->a[i].isPinned );
|
||||||
p->a[i].key = newKey;
|
p->a[i].key = newKey;
|
||||||
@@ -422,7 +431,7 @@ void installTestPCache(
|
|||||||
unsigned prngSeed, /* Seed for the PRNG */
|
unsigned prngSeed, /* Seed for the PRNG */
|
||||||
unsigned highStress /* Call xStress agressively */
|
unsigned highStress /* Call xStress agressively */
|
||||||
){
|
){
|
||||||
static const sqlite3_pcache_methods testPcache = {
|
static const sqlite3_pcache_methods2 testPcache = {
|
||||||
(void*)&testpcacheGlobal,
|
(void*)&testpcacheGlobal,
|
||||||
testpcacheInit,
|
testpcacheInit,
|
||||||
testpcacheShutdown,
|
testpcacheShutdown,
|
||||||
@@ -435,7 +444,7 @@ void installTestPCache(
|
|||||||
testpcacheTruncate,
|
testpcacheTruncate,
|
||||||
testpcacheDestroy,
|
testpcacheDestroy,
|
||||||
};
|
};
|
||||||
static sqlite3_pcache_methods defaultPcache;
|
static sqlite3_pcache_methods2 defaultPcache;
|
||||||
static int isInstalled = 0;
|
static int isInstalled = 0;
|
||||||
|
|
||||||
assert( testpcacheGlobal.nInstance==0 );
|
assert( testpcacheGlobal.nInstance==0 );
|
||||||
@@ -446,12 +455,12 @@ void installTestPCache(
|
|||||||
testpcacheGlobal.highStress = highStress;
|
testpcacheGlobal.highStress = highStress;
|
||||||
if( installFlag!=isInstalled ){
|
if( installFlag!=isInstalled ){
|
||||||
if( installFlag ){
|
if( installFlag ){
|
||||||
sqlite3_config(SQLITE_CONFIG_GETPCACHE, &defaultPcache);
|
sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &defaultPcache);
|
||||||
assert( defaultPcache.xCreate!=testpcacheCreate );
|
assert( defaultPcache.xCreate!=testpcacheCreate );
|
||||||
sqlite3_config(SQLITE_CONFIG_PCACHE, &testPcache);
|
sqlite3_config(SQLITE_CONFIG_PCACHE2, &testPcache);
|
||||||
}else{
|
}else{
|
||||||
assert( defaultPcache.xCreate!=0 );
|
assert( defaultPcache.xCreate!=0 );
|
||||||
sqlite3_config(SQLITE_CONFIG_PCACHE, &defaultPcache);
|
sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultPcache);
|
||||||
}
|
}
|
||||||
isInstalled = installFlag;
|
isInstalled = installFlag;
|
||||||
}
|
}
|
||||||
|
@@ -68,7 +68,7 @@ proc reset_highwater_marks {} {
|
|||||||
sqlite3_status SQLITE_STATUS_PARSER_STACK 1
|
sqlite3_status SQLITE_STATUS_PARSER_STACK 1
|
||||||
}
|
}
|
||||||
|
|
||||||
set xtra_size 256
|
set xtra_size 272
|
||||||
|
|
||||||
# Test 1: Both PAGECACHE and SCRATCH are shut down.
|
# Test 1: Both PAGECACHE and SCRATCH are shut down.
|
||||||
#
|
#
|
||||||
|
Reference in New Issue
Block a user