mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Fix a resource leak introduced by the change-counter optimisation. Also add some test coverage. (CVS 3790)
FossilOrigin-Name: ba0538a4977aefd6645554f1989f0a98b540b9cd
This commit is contained in:
25
manifest
25
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Update\sthe\sversion\snumber\sand\schange\scomments\sin\spreparation\sfor\sthe\nrelease\sof\s3.3.14.\s(CVS\s3789)
|
C Fix\sa\sresource\sleak\sintroduced\sby\sthe\schange-counter\soptimisation.\sAlso\sadd\ssome\stest\scoverage.\s(CVS\s3790)
|
||||||
D 2007-04-02T00:53:19
|
D 2007-04-02T05:07:47
|
||||||
F Makefile.in 2f2c3bf69faf0ae7b8e8af4f94f1986849034530
|
F Makefile.in 2f2c3bf69faf0ae7b8e8af4f94f1986849034530
|
||||||
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
@@ -58,7 +58,7 @@ F src/alter.c 2c79ec40f65e33deaf90ca493422c74586e481a3
|
|||||||
F src/analyze.c 4bbf5ddf9680587c6d4917e02e378b6037be3651
|
F src/analyze.c 4bbf5ddf9680587c6d4917e02e378b6037be3651
|
||||||
F src/attach.c a16ada4a4654a0d126b8223ec9494ebb81bc5c3c
|
F src/attach.c a16ada4a4654a0d126b8223ec9494ebb81bc5c3c
|
||||||
F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f
|
F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f
|
||||||
F src/btree.c 052d0306d66768ad4d5a54609d4464bdc2a17839
|
F src/btree.c 48fa58f2d71edeab4a7d08157abe50a0b7a0e489
|
||||||
F src/btree.h 9b2cc0d113c0bc2d37d244b9a394d56948c9acbf
|
F src/btree.h 9b2cc0d113c0bc2d37d244b9a394d56948c9acbf
|
||||||
F src/build.c ad3374b5409554e504300f77e1fbc6b4c106a57f
|
F src/build.c ad3374b5409554e504300f77e1fbc6b4c106a57f
|
||||||
F src/callback.c 31d22b4919c7645cbcbb1591ce2453e8c677c558
|
F src/callback.c 31d22b4919c7645cbcbb1591ce2453e8c677c558
|
||||||
@@ -86,7 +86,7 @@ F src/os_unix.c ccb003fb9fadc032924d3efb3fa8cc69fd9e176b
|
|||||||
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
|
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
|
||||||
F src/os_win.c c9a99524d6b2bdec636264cad1b67553925e3309
|
F src/os_win.c c9a99524d6b2bdec636264cad1b67553925e3309
|
||||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||||
F src/pager.c 84072e9b5f370752176e5f7575557496bf239bc3
|
F src/pager.c a73e3b06cf315bfa70d34d9d311d3395693eef87
|
||||||
F src/pager.h e79a24cf200b8771366217f5bca414f5b7823f42
|
F src/pager.h e79a24cf200b8771366217f5bca414f5b7823f42
|
||||||
F src/parse.y 207ab04273ae13aa4a729b96008d294d5f334ab3
|
F src/parse.y 207ab04273ae13aa4a729b96008d294d5f334ab3
|
||||||
F src/pragma.c 3b992b5b2640d6ae25cef05aa6a42cd1d6c43234
|
F src/pragma.c 3b992b5b2640d6ae25cef05aa6a42cd1d6c43234
|
||||||
@@ -102,7 +102,7 @@ F src/sqliteInt.h 09384eb30d6740e3e9d0c9379432e254fdb390d9
|
|||||||
F src/table.c 6d0da66dde26ee75614ed8f584a1996467088d06
|
F src/table.c 6d0da66dde26ee75614ed8f584a1996467088d06
|
||||||
F src/tclsqlite.c a8d1166319db5d505b25ac6a9820162afe63fc8a
|
F src/tclsqlite.c a8d1166319db5d505b25ac6a9820162afe63fc8a
|
||||||
F src/test1.c 0f94df69cd8832799aafaf58f7e28b4527225a3e
|
F src/test1.c 0f94df69cd8832799aafaf58f7e28b4527225a3e
|
||||||
F src/test2.c 710a7252e22a8c690136a2b609e90fdad2697f35
|
F src/test2.c 24458b17ab2f3c90cbc1c8446bd7ffe69be62f88
|
||||||
F src/test3.c 65f92247cf8592854e9bf5115b3fb711f8b33280
|
F src/test3.c 65f92247cf8592854e9bf5115b3fb711f8b33280
|
||||||
F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25
|
F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25
|
||||||
F src/test5.c 7162f8526affb771c4ed256826eee7bb9eca265f
|
F src/test5.c 7162f8526affb771c4ed256826eee7bb9eca265f
|
||||||
@@ -168,6 +168,7 @@ F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027
|
|||||||
F test/btree7.test a6d3b842db22af97dd14b989e90a2fd96066b72f
|
F test/btree7.test a6d3b842db22af97dd14b989e90a2fd96066b72f
|
||||||
F test/btree8.test fadc112bcbd6a0c622d34c813fc8a648eacf8804
|
F test/btree8.test fadc112bcbd6a0c622d34c813fc8a648eacf8804
|
||||||
F test/busy.test 0271c854738e23ad76e10d4096a698e5af29d211
|
F test/busy.test 0271c854738e23ad76e10d4096a698e5af29d211
|
||||||
|
F test/cache.test 02cd1d1b0e7ad59cf24b85d49d77705e33aa5224
|
||||||
F test/capi2.test 7ecc9b342cc9ec27b53bbf95724cf2e5874fd496
|
F test/capi2.test 7ecc9b342cc9ec27b53bbf95724cf2e5874fd496
|
||||||
F test/capi3.test 1675323145d128e5942a9faffcfd5cf4e219a33f
|
F test/capi3.test 1675323145d128e5942a9faffcfd5cf4e219a33f
|
||||||
F test/capi3b.test 5f0bc94b104e11086b1103b20277e1910f59c7f4
|
F test/capi3b.test 5f0bc94b104e11086b1103b20277e1910f59c7f4
|
||||||
@@ -261,7 +262,7 @@ F test/malloc.test d868a6b98b07928b00bca3d9874daf6885c86150
|
|||||||
F test/malloc2.test 4ed7d719542c4570dec9c2ebe2bbdf3a9f3b0d05
|
F test/malloc2.test 4ed7d719542c4570dec9c2ebe2bbdf3a9f3b0d05
|
||||||
F test/malloc3.test e965954b6f808876a63d3101fd70370320b509a7
|
F test/malloc3.test e965954b6f808876a63d3101fd70370320b509a7
|
||||||
F test/malloc4.test 59cd02f71b363302a04c4e77b97c0a1572eaa210
|
F test/malloc4.test 59cd02f71b363302a04c4e77b97c0a1572eaa210
|
||||||
F test/malloc5.test 7425272e263325fda7d32cb55706e52b5c09e7e0
|
F test/malloc5.test 17a32bd72073741d539bb2a1307d712a316b89da
|
||||||
F test/malloc6.test 025ae0b78542e0ddd000d23f79d93e9be9ba0f15
|
F test/malloc6.test 025ae0b78542e0ddd000d23f79d93e9be9ba0f15
|
||||||
F test/malloc7.test 1cf52834509eac7ebeb92105dacd4669f9ca9869
|
F test/malloc7.test 1cf52834509eac7ebeb92105dacd4669f9ca9869
|
||||||
F test/manydb.test 8de36b8d33aab5ef295b11d9e95310aeded31af8
|
F test/manydb.test 8de36b8d33aab5ef295b11d9e95310aeded31af8
|
||||||
@@ -274,11 +275,11 @@ F test/misc3.test 7bd937e2c62bcc6be71939faf068d506467b1e03
|
|||||||
F test/misc4.test b043a05dea037cca5989f3ae09552fa16119bc80
|
F test/misc4.test b043a05dea037cca5989f3ae09552fa16119bc80
|
||||||
F test/misc5.test c7d2d2a5a20dc37d3605a8067f0df5af2240122e
|
F test/misc5.test c7d2d2a5a20dc37d3605a8067f0df5af2240122e
|
||||||
F test/misc6.test 3de55ec5cadf466ada587173faa5d6a4790a8bb7
|
F test/misc6.test 3de55ec5cadf466ada587173faa5d6a4790a8bb7
|
||||||
F test/misc7.test 8663e29f1a57c55321d4e6a8b2b9203d33254c69
|
F test/misc7.test db026378fd83c9a318a9b5f5db5c17725db450d9
|
||||||
F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33
|
F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33
|
||||||
F test/notnull.test 44d600f916b770def8b095a9962dbe3be5a70d82
|
F test/notnull.test 44d600f916b770def8b095a9962dbe3be5a70d82
|
||||||
F test/null.test 9503e1f63e959544c006d9f01709c5b5eab67d54
|
F test/null.test 9503e1f63e959544c006d9f01709c5b5eab67d54
|
||||||
F test/pager.test ceeef3caac4bf2046c6c06827f1a87dc1dec30f3
|
F test/pager.test 3e12bef9c8512adb3f5db13d5745dc68fb4b92fc
|
||||||
F test/pager2.test c025f91b75fe65e85febda64d9416428b8a5cab5
|
F test/pager2.test c025f91b75fe65e85febda64d9416428b8a5cab5
|
||||||
F test/pager3.test 2323bf27fd5bd887b580247e5bce500ceee994b4
|
F test/pager3.test 2323bf27fd5bd887b580247e5bce500ceee994b4
|
||||||
F test/pagesize.test 05c74ea49f790734ec1e9ab765d9bf1cce79b8f2
|
F test/pagesize.test 05c74ea49f790734ec1e9ab765d9bf1cce79b8f2
|
||||||
@@ -447,7 +448,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||||
P 18aec1ddfb08b74f0ef9cf1215eac7af71449db3
|
P d9f6fdb72b29354921e6de40df5ed4f86b158a01
|
||||||
R 1ba2c076c76000f21aa292bb0a8f72c4
|
R ac656430c79d0852aed9fac02cb5a8d8
|
||||||
U drh
|
U danielk1977
|
||||||
Z ab035ae84bd6530ffbee25f61451be81
|
Z 6f28f4d19e867b11a92da6fb2f139223
|
||||||
|
@@ -1 +1 @@
|
|||||||
d9f6fdb72b29354921e6de40df5ed4f86b158a01
|
ba0538a4977aefd6645554f1989f0a98b540b9cd
|
13
src/btree.c
13
src/btree.c
@@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** $Id: btree.c,v 1.349 2007/03/31 02:36:44 drh Exp $
|
** $Id: btree.c,v 1.350 2007/04/02 05:07:47 danielk1977 Exp $
|
||||||
**
|
**
|
||||||
** This file implements a external (disk-based) database using BTrees.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** For a detailed discussion of BTrees, refer to
|
** For a detailed discussion of BTrees, refer to
|
||||||
@@ -2280,8 +2280,13 @@ static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
|
|||||||
/*
|
/*
|
||||||
** This routine is called prior to sqlite3PagerCommit when a transaction
|
** This routine is called prior to sqlite3PagerCommit when a transaction
|
||||||
** is commited for an auto-vacuum database.
|
** is commited for an auto-vacuum database.
|
||||||
|
**
|
||||||
|
** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages
|
||||||
|
** the database file should be truncated to during the commit process.
|
||||||
|
** i.e. the database has been reorganized so that only the first *pnTrunc
|
||||||
|
** pages are in use.
|
||||||
*/
|
*/
|
||||||
static int autoVacuumCommit(BtShared *pBt, Pgno *nTrunc){
|
static int autoVacuumCommit(BtShared *pBt, Pgno *pnTrunc){
|
||||||
Pager *pPager = pBt->pPager;
|
Pager *pPager = pBt->pPager;
|
||||||
Pgno nFreeList; /* Number of pages remaining on the free-list. */
|
Pgno nFreeList; /* Number of pages remaining on the free-list. */
|
||||||
int nPtrMap; /* Number of pointer-map pages deallocated */
|
int nPtrMap; /* Number of pointer-map pages deallocated */
|
||||||
@@ -2310,7 +2315,7 @@ static int autoVacuumCommit(BtShared *pBt, Pgno *nTrunc){
|
|||||||
*/
|
*/
|
||||||
nFreeList = get4byte(&pBt->pPage1->aData[36]);
|
nFreeList = get4byte(&pBt->pPage1->aData[36]);
|
||||||
if( nFreeList==0 ){
|
if( nFreeList==0 ){
|
||||||
*nTrunc = 0;
|
*pnTrunc = 0;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2401,7 +2406,7 @@ static int autoVacuumCommit(BtShared *pBt, Pgno *nTrunc){
|
|||||||
if( rc!=SQLITE_OK ) goto autovacuum_out;
|
if( rc!=SQLITE_OK ) goto autovacuum_out;
|
||||||
put4byte(&pBt->pPage1->aData[32], 0);
|
put4byte(&pBt->pPage1->aData[32], 0);
|
||||||
put4byte(&pBt->pPage1->aData[36], 0);
|
put4byte(&pBt->pPage1->aData[36], 0);
|
||||||
*nTrunc = finSize;
|
*pnTrunc = finSize;
|
||||||
assert( finSize!=PENDING_BYTE_PAGE(pBt) );
|
assert( finSize!=PENDING_BYTE_PAGE(pBt) );
|
||||||
|
|
||||||
autovacuum_out:
|
autovacuum_out:
|
||||||
|
141
src/pager.c
141
src/pager.c
@@ -18,7 +18,7 @@
|
|||||||
** file simultaneously, or one process from reading the database while
|
** file simultaneously, or one process from reading the database while
|
||||||
** another is writing.
|
** another is writing.
|
||||||
**
|
**
|
||||||
** @(#) $Id: pager.c,v 1.313 2007/04/01 23:49:52 drh Exp $
|
** @(#) $Id: pager.c,v 1.314 2007/04/02 05:07:47 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_DISKIO
|
#ifndef SQLITE_OMIT_DISKIO
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
@@ -2389,9 +2389,16 @@ static PgHdr *merge_pagelist(PgHdr *pA, PgHdr *pB){
|
|||||||
** connected by pDirty pointers. The pPrevDirty pointers are
|
** connected by pDirty pointers. The pPrevDirty pointers are
|
||||||
** corrupted by this sort.
|
** corrupted by this sort.
|
||||||
*/
|
*/
|
||||||
#define N_SORT_BUCKET 25
|
#define N_SORT_BUCKET_ALLOC 25
|
||||||
|
#define N_SORT_BUCKET 25
|
||||||
|
#ifdef SQLITE_TEST
|
||||||
|
int sqlite3_pager_n_sort_bucket = 0;
|
||||||
|
#undef N_SORT_BUCKET
|
||||||
|
#define N_SORT_BUCKET \
|
||||||
|
(sqlite3_pager_n_sort_bucket?sqlite3_pager_n_sort_bucket:N_SORT_BUCKET_ALLOC)
|
||||||
|
#endif
|
||||||
static PgHdr *sort_pagelist(PgHdr *pIn){
|
static PgHdr *sort_pagelist(PgHdr *pIn){
|
||||||
PgHdr *a[N_SORT_BUCKET], *p;
|
PgHdr *a[N_SORT_BUCKET_ALLOC], *p;
|
||||||
int i;
|
int i;
|
||||||
memset(a, 0, sizeof(a));
|
memset(a, 0, sizeof(a));
|
||||||
while( pIn ){
|
while( pIn ){
|
||||||
@@ -2408,6 +2415,11 @@ static PgHdr *sort_pagelist(PgHdr *pIn){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( i==N_SORT_BUCKET-1 ){
|
if( i==N_SORT_BUCKET-1 ){
|
||||||
|
/* Coverage: To get here, there need to be 2^(N_SORT_BUCKET)
|
||||||
|
** elements in the input list. This is possible, but impractical.
|
||||||
|
** Testing this line is the point of global variable
|
||||||
|
** sqlite3_pager_n_sort_bucket.
|
||||||
|
*/
|
||||||
a[i] = merge_pagelist(a[i], p);
|
a[i] = merge_pagelist(a[i], p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2591,7 +2603,9 @@ static int pager_recycle(Pager *pPager, int syncOk, PgHdr **ppPg){
|
|||||||
/* Unlink the old page from the free list and the hash table
|
/* Unlink the old page from the free list and the hash table
|
||||||
*/
|
*/
|
||||||
unlinkPage(pPg);
|
unlinkPage(pPg);
|
||||||
TEST_INCR(pPager->nOvfl);
|
if( pPg && pPg->pgno!=0 ){
|
||||||
|
TEST_INCR(pPager->nOvfl);
|
||||||
|
}
|
||||||
|
|
||||||
*ppPg = pPg;
|
*ppPg = pPg;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
@@ -2771,9 +2785,32 @@ static int pagerSharedLock(Pager *pPager){
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( pPager->pAll ){
|
if( pPager->pAll ){
|
||||||
|
/* The shared-lock has just been acquired on the database file
|
||||||
|
** and there are already pages in the cache (from a previous
|
||||||
|
** read or write transaction). If the value of the change-counter
|
||||||
|
** stored in Pager.iChangeCount matches that found on page 1 of
|
||||||
|
** the database file, then no database changes have occured since
|
||||||
|
** the cache was last valid and it is safe to retain the cached
|
||||||
|
** pages. Otherwise, if Pager.iChangeCount does not match the
|
||||||
|
** change-counter on page 1 of the file, the current cache contents
|
||||||
|
** must be discarded.
|
||||||
|
*/
|
||||||
|
|
||||||
PgHdr *pPage1 = pager_lookup(pPager, 1);
|
PgHdr *pPage1 = pager_lookup(pPager, 1);
|
||||||
if( pPage1 ){
|
if( pPage1 ){
|
||||||
unlinkHashChain(pPager, pPage1);
|
unlinkPage(pPage1);
|
||||||
|
|
||||||
|
assert( pPager->pFirst==pPager->pFirstSynced );
|
||||||
|
pPage1->pNextFree = pPager->pFirst;
|
||||||
|
if( pPager->pFirst ){
|
||||||
|
pPager->pFirst->pPrevFree = pPage1;
|
||||||
|
}else{
|
||||||
|
assert( !pPager->pLast );
|
||||||
|
pPager->pLast = pPage1;
|
||||||
|
}
|
||||||
|
pPager->pFirst = pPage1;
|
||||||
|
pPager->pFirstSynced = pPage1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( !pager_lookup(pPager, 1) );
|
assert( !pager_lookup(pPager, 1) );
|
||||||
@@ -2802,6 +2839,60 @@ static int pagerSharedLock(Pager *pPager){
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Allocate or recycle space for a single page.
|
||||||
|
*/
|
||||||
|
static int pagerAllocatePage(Pager *pPager, PgHdr **ppPg){
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
PgHdr *pPg;
|
||||||
|
|
||||||
|
if( !(pPager->pFirstSynced && pPager->pFirstSynced->pgno==0) && (
|
||||||
|
pPager->nPage<pPager->mxPage || pPager->pFirst==0 || MEMDB ||
|
||||||
|
(pPager->pFirstSynced==0 && pPager->doNotSync)
|
||||||
|
) ){
|
||||||
|
/* Create a new page */
|
||||||
|
if( pPager->nPage>=pPager->nHash ){
|
||||||
|
pager_resize_hash_table(pPager,
|
||||||
|
pPager->nHash<256 ? 256 : pPager->nHash*2);
|
||||||
|
if( pPager->nHash==0 ){
|
||||||
|
rc = SQLITE_NOMEM;
|
||||||
|
goto pager_allocate_out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->pageSize
|
||||||
|
+ sizeof(u32) + pPager->nExtra
|
||||||
|
+ MEMDB*sizeof(PgHistory) );
|
||||||
|
if( pPg==0 ){
|
||||||
|
rc = SQLITE_NOMEM;
|
||||||
|
goto pager_allocate_out;
|
||||||
|
}
|
||||||
|
memset(pPg, 0, sizeof(*pPg));
|
||||||
|
if( MEMDB ){
|
||||||
|
memset(PGHDR_TO_HIST(pPg, pPager), 0, sizeof(PgHistory));
|
||||||
|
}
|
||||||
|
pPg->pPager = pPager;
|
||||||
|
pPg->pNextAll = pPager->pAll;
|
||||||
|
pPager->pAll = pPg;
|
||||||
|
pPager->nPage++;
|
||||||
|
if( pPager->nPage>pPager->nMaxPage ){
|
||||||
|
assert( pPager->nMaxPage==(pPager->nPage-1) );
|
||||||
|
pPager->nMaxPage++;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
/* Recycle an existing page with a zero ref-count. */
|
||||||
|
rc = pager_recycle(pPager, 1, &pPg);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
goto pager_allocate_out;
|
||||||
|
}
|
||||||
|
assert( pPager->state>=SHARED_LOCK );
|
||||||
|
assert(pPg);
|
||||||
|
}
|
||||||
|
*ppPg = pPg;
|
||||||
|
|
||||||
|
pager_allocate_out:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Acquire a page.
|
** Acquire a page.
|
||||||
**
|
**
|
||||||
@@ -2867,43 +2958,11 @@ int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag){
|
|||||||
int nMax;
|
int nMax;
|
||||||
int h;
|
int h;
|
||||||
TEST_INCR(pPager->nMiss);
|
TEST_INCR(pPager->nMiss);
|
||||||
if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 || MEMDB ||
|
rc = pagerAllocatePage(pPager, &pPg);
|
||||||
(pPager->pFirstSynced==0 && pPager->doNotSync)
|
if( rc!=SQLITE_OK ){
|
||||||
){
|
return rc;
|
||||||
/* Create a new page */
|
|
||||||
if( pPager->nPage>=pPager->nHash ){
|
|
||||||
pager_resize_hash_table(pPager,
|
|
||||||
pPager->nHash<256 ? 256 : pPager->nHash*2);
|
|
||||||
if( pPager->nHash==0 ){
|
|
||||||
return SQLITE_NOMEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->pageSize
|
|
||||||
+ sizeof(u32) + pPager->nExtra
|
|
||||||
+ MEMDB*sizeof(PgHistory) );
|
|
||||||
if( pPg==0 ){
|
|
||||||
return SQLITE_NOMEM;
|
|
||||||
}
|
|
||||||
memset(pPg, 0, sizeof(*pPg));
|
|
||||||
if( MEMDB ){
|
|
||||||
memset(PGHDR_TO_HIST(pPg, pPager), 0, sizeof(PgHistory));
|
|
||||||
}
|
|
||||||
pPg->pPager = pPager;
|
|
||||||
pPg->pNextAll = pPager->pAll;
|
|
||||||
pPager->pAll = pPg;
|
|
||||||
pPager->nPage++;
|
|
||||||
if( pPager->nPage>pPager->nMaxPage ){
|
|
||||||
assert( pPager->nMaxPage==(pPager->nPage-1) );
|
|
||||||
pPager->nMaxPage++;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
rc = pager_recycle(pPager, 1, &pPg);
|
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
assert( pPager->state>=SHARED_LOCK );
|
|
||||||
assert(pPg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pPg->pgno = pgno;
|
pPg->pgno = pgno;
|
||||||
if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
|
if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
|
||||||
sqlite3CheckMemory(pPager->aInJournal, pgno/8);
|
sqlite3CheckMemory(pPager->aInJournal, pgno/8);
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
** is not included in the SQLite library. It is used for automated
|
** is not included in the SQLite library. It is used for automated
|
||||||
** testing of the SQLite library.
|
** testing of the SQLite library.
|
||||||
**
|
**
|
||||||
** $Id: test2.c,v 1.42 2007/03/30 14:06:34 drh Exp $
|
** $Id: test2.c,v 1.43 2007/04/02 05:07:47 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -570,6 +570,7 @@ int Sqlitetest2_Init(Tcl_Interp *interp){
|
|||||||
extern int sqlite3_io_error_hit;
|
extern int sqlite3_io_error_hit;
|
||||||
extern int sqlite3_diskfull_pending;
|
extern int sqlite3_diskfull_pending;
|
||||||
extern int sqlite3_diskfull;
|
extern int sqlite3_diskfull;
|
||||||
|
extern int sqlite3_pager_n_sort_bucket;
|
||||||
static struct {
|
static struct {
|
||||||
char *zName;
|
char *zName;
|
||||||
Tcl_CmdProc *xProc;
|
Tcl_CmdProc *xProc;
|
||||||
@@ -612,5 +613,7 @@ int Sqlitetest2_Init(Tcl_Interp *interp){
|
|||||||
(char*)&sqlite3_pending_byte, TCL_LINK_INT);
|
(char*)&sqlite3_pending_byte, TCL_LINK_INT);
|
||||||
Tcl_LinkVar(interp, "pager_pagesize",
|
Tcl_LinkVar(interp, "pager_pagesize",
|
||||||
(char*)&test_pagesize, TCL_LINK_INT);
|
(char*)&test_pagesize, TCL_LINK_INT);
|
||||||
|
Tcl_LinkVar(interp, "sqlite_pager_n_sort_bucket",
|
||||||
|
(char*)&sqlite3_pager_n_sort_bucket, TCL_LINK_INT);
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
58
test/cache.test
Normal file
58
test/cache.test
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
# 2007 March 24
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
#
|
||||||
|
# $Id: cache.test,v 1.1 2007/04/02 05:07:48 danielk1977 Exp $
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
|
||||||
|
ifcapable {!pager_pragmas} {
|
||||||
|
finish_test
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
proc pager_cache_size {db} {
|
||||||
|
set bt [btree_from_db $db]
|
||||||
|
array set stats [btree_pager_stats $bt]
|
||||||
|
return $stats(page)
|
||||||
|
}
|
||||||
|
|
||||||
|
do_test cache-1.1 {
|
||||||
|
pager_cache_size db
|
||||||
|
} {0}
|
||||||
|
|
||||||
|
do_test cache-1.2 {
|
||||||
|
execsql {
|
||||||
|
CREATE TABLE abc(a, b, c);
|
||||||
|
INSERT INTO abc VALUES(1, 2, 3);
|
||||||
|
}
|
||||||
|
pager_cache_size db
|
||||||
|
} {2}
|
||||||
|
|
||||||
|
# At one point, repeatedly locking and unlocking the cache was causing
|
||||||
|
# a resource leak of one page per repetition. The page wasn't actually
|
||||||
|
# leaked, but would not be reused until the pager-cache was full (i.e.
|
||||||
|
# 2000 pages by default).
|
||||||
|
#
|
||||||
|
# This tests that once the pager-cache is initialised, it can be locked
|
||||||
|
# and unlocked repeatedly without internally allocating any new pages.
|
||||||
|
#
|
||||||
|
set cache_size [pager_cache_size db]
|
||||||
|
for {set ii 0} {$ii < 10} {incr ii} {
|
||||||
|
|
||||||
|
do_test cache-1.3.$ii {
|
||||||
|
execsql {SELECT * FROM abc}
|
||||||
|
pager_cache_size db
|
||||||
|
} $::cache_size
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
finish_test
|
@@ -12,7 +12,7 @@
|
|||||||
# This file contains test cases focused on the two memory-management APIs,
|
# This file contains test cases focused on the two memory-management APIs,
|
||||||
# sqlite3_soft_heap_limit() and sqlite3_release_memory().
|
# sqlite3_soft_heap_limit() and sqlite3_release_memory().
|
||||||
#
|
#
|
||||||
# $Id: malloc5.test,v 1.7 2006/01/19 08:43:32 danielk1977 Exp $
|
# $Id: malloc5.test,v 1.8 2007/04/02 05:07:48 danielk1977 Exp $
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# NOTES ON EXPECTED BEHAVIOUR
|
# NOTES ON EXPECTED BEHAVIOUR
|
||||||
@@ -85,6 +85,7 @@ do_test malloc5-1.4 {
|
|||||||
do_test malloc5-1.5 {
|
do_test malloc5-1.5 {
|
||||||
# Manipulate the cache so that it contains two unused pages. One requires
|
# Manipulate the cache so that it contains two unused pages. One requires
|
||||||
# a journal-sync to free, the other does not.
|
# a journal-sync to free, the other does not.
|
||||||
|
db2 close
|
||||||
execsql {
|
execsql {
|
||||||
SELECT * FROM abc;
|
SELECT * FROM abc;
|
||||||
CREATE TABLE def(d, e, f);
|
CREATE TABLE def(d, e, f);
|
||||||
@@ -95,6 +96,7 @@ do_test malloc5-1.6 {
|
|||||||
# Database should not be locked this time. The above test case only
|
# Database should not be locked this time. The above test case only
|
||||||
# requested 500 bytes of memory, which can be obtained by freeing the page
|
# requested 500 bytes of memory, which can be obtained by freeing the page
|
||||||
# that does not require an fsync().
|
# that does not require an fsync().
|
||||||
|
sqlite3 db2 test.db
|
||||||
catchsql {
|
catchsql {
|
||||||
SELECT * FROM abc;
|
SELECT * FROM abc;
|
||||||
} db2
|
} db2
|
||||||
@@ -102,9 +104,11 @@ do_test malloc5-1.6 {
|
|||||||
do_test malloc5-1.7 {
|
do_test malloc5-1.7 {
|
||||||
# Release another 500 bytes of memory. This time we require a sync(),
|
# Release another 500 bytes of memory. This time we require a sync(),
|
||||||
# so the database file will be locked afterwards.
|
# so the database file will be locked afterwards.
|
||||||
|
db2 close
|
||||||
sqlite3_release_memory 500
|
sqlite3_release_memory 500
|
||||||
} $::pgalloc
|
} $::pgalloc
|
||||||
do_test malloc5-1.8 {
|
do_test malloc5-1.8 {
|
||||||
|
sqlite3 db2 test.db
|
||||||
catchsql {
|
catchsql {
|
||||||
SELECT * FROM abc;
|
SELECT * FROM abc;
|
||||||
} db2
|
} db2
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# This file implements regression tests for SQLite library.
|
# This file implements regression tests for SQLite library.
|
||||||
#
|
#
|
||||||
# $Id: misc7.test,v 1.9 2007/03/31 10:00:49 danielk1977 Exp $
|
# $Id: misc7.test,v 1.10 2007/04/02 05:07:48 danielk1977 Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -158,7 +158,8 @@ do_test misc7-7.2 {
|
|||||||
}
|
}
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
# Test malloc failure whilst installing a foriegn key.
|
# Test the UTF-16 version of the "out of memory" message (used when
|
||||||
|
# malloc fails during sqlite3_open() ).
|
||||||
#
|
#
|
||||||
ifcapable utf16 {
|
ifcapable utf16 {
|
||||||
do_test misc7-8 {
|
do_test misc7-8 {
|
||||||
@@ -327,7 +328,15 @@ do_ioerr_test misc7-16 -sqlprep {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sqlite3 db test.db
|
||||||
|
set sqlite_pager_n_sort_bucket 4
|
||||||
|
do_test misc7-17 {
|
||||||
|
execsql {
|
||||||
|
PRAGMA integrity_check;
|
||||||
|
VACUUM;
|
||||||
|
PRAGMA integrity_check;
|
||||||
|
}
|
||||||
|
} {ok ok}
|
||||||
|
set sqlite_pager_n_sort_bucket 0
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this script is page cache subsystem.
|
# focus of this script is page cache subsystem.
|
||||||
#
|
#
|
||||||
# $Id: pager.test,v 1.26 2007/03/23 18:12:07 danielk1977 Exp $
|
# $Id: pager.test,v 1.27 2007/04/02 05:07:48 danielk1977 Exp $
|
||||||
|
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
@@ -119,7 +119,7 @@ do_test pager-2.12 {
|
|||||||
} {1}
|
} {1}
|
||||||
do_test pager-2.13 {
|
do_test pager-2.13 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 1 page 2 max 10 size 0 state 1 err 0 hit 1 miss 2 ovfl 0}
|
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 1 miss 2 ovfl 0}
|
||||||
do_test pager-2.14 {
|
do_test pager-2.14 {
|
||||||
set v [catch {
|
set v [catch {
|
||||||
page_write $::g1 "Page-One"
|
page_write $::g1 "Page-One"
|
||||||
@@ -128,7 +128,7 @@ do_test pager-2.14 {
|
|||||||
} {0 {}}
|
} {0 {}}
|
||||||
do_test pager-2.15 {
|
do_test pager-2.15 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 1 page 2 max 10 size 1 state 2 err 0 hit 1 miss 2 ovfl 0}
|
} {ref 1 page 1 max 10 size 1 state 2 err 0 hit 1 miss 2 ovfl 0}
|
||||||
do_test pager-2.16 {
|
do_test pager-2.16 {
|
||||||
page_read $::g1
|
page_read $::g1
|
||||||
} {Page-One}
|
} {Page-One}
|
||||||
@@ -140,19 +140,19 @@ do_test pager-2.17 {
|
|||||||
} {0 {}}
|
} {0 {}}
|
||||||
do_test pager-2.20 {
|
do_test pager-2.20 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 1 page 2 max 10 size -1 state 1 err 0 hit 2 miss 2 ovfl 0}
|
} {ref 1 page 1 max 10 size -1 state 1 err 0 hit 2 miss 2 ovfl 0}
|
||||||
do_test pager-2.19 {
|
do_test pager-2.19 {
|
||||||
pager_pagecount $::p1
|
pager_pagecount $::p1
|
||||||
} {1}
|
} {1}
|
||||||
do_test pager-2.21 {
|
do_test pager-2.21 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 1 page 2 max 10 size 1 state 1 err 0 hit 2 miss 2 ovfl 0}
|
} {ref 1 page 1 max 10 size 1 state 1 err 0 hit 2 miss 2 ovfl 0}
|
||||||
do_test pager-2.22 {
|
do_test pager-2.22 {
|
||||||
page_unref $::g1
|
page_unref $::g1
|
||||||
} {}
|
} {}
|
||||||
do_test pager-2.23 {
|
do_test pager-2.23 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 0 page 2 max 10 size -1 state 0 err 0 hit 2 miss 2 ovfl 0}
|
} {ref 0 page 1 max 10 size -1 state 0 err 0 hit 2 miss 2 ovfl 0}
|
||||||
do_test pager-2.24 {
|
do_test pager-2.24 {
|
||||||
set v [catch {
|
set v [catch {
|
||||||
page_get $::p1 1
|
page_get $::p1 1
|
||||||
|
Reference in New Issue
Block a user