Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b6ae41ab93 | |||
| 387dd1bffc |
@@ -1,5 +1,5 @@
|
||||
C Add\sa\sversion\snumber\sto\sthe\ssqlite3_pcache_methods2\sobject.\s\sOther\sPCACHE2\ndocumentation\simprovements.
|
||||
D 2011-11-13T21:44:03.995
|
||||
C Further\swork\son\smmap().\s\sStill\sdoes\snot\swork\sright\s-\sautovacuum\stests\sare\sthe\nfirst\sto\sfail.
|
||||
D 2011-11-14T12:34:15.531
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@@ -125,7 +125,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
||||
F src/backup.c 4368158da74d4711888e03264105c5c527d76caf
|
||||
F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef
|
||||
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||
F src/btree.c 149cccf2134f555583d0825e47b17104aa06cb84
|
||||
F src/btree.c c683806cd69ae845d5093d6e2906a7a73a2d9775
|
||||
F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce
|
||||
F src/btreeInt.h ea863a819224d3e6845ad1e39954d41558b8cd8b
|
||||
F src/build.c 8af67a08a852ff4c63701963cb1ab7166f577814
|
||||
@@ -162,17 +162,17 @@ F src/mutex_os2.c 882d735098c07c8c6a5472b8dd66e19675fe117f
|
||||
F src/mutex_unix.c b4f4e923bb8de93ec3f251fadb50855f23df9579
|
||||
F src/mutex_w32.c 5e54f3ba275bcb5d00248b8c23107df2e2f73e33
|
||||
F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
|
||||
F src/os.c 5d9b02782ed36345348d6fe21d7762ed3a9cfd2a
|
||||
F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
|
||||
F src/os.c ac54d2199b0bd16543a179d8376deccbe2b4f699
|
||||
F src/os.h 1e4f937e1315710bd4a34347d7ddffc1f8cb9055
|
||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||
F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440
|
||||
F src/os_unix.c 4fbb91726165e105c1679a2660f49a3f4c376e4f
|
||||
F src/os_unix.c f2c4cfdc350f9b1c5b6ff5079b65c875dc5ea35d
|
||||
F src/os_win.c d6cf718667c4d89d930f30caa6cdc7f7753e259a
|
||||
F src/pager.c db33d4bf1e3e019c34c220971cc6c3aa07c30f54
|
||||
F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d
|
||||
F src/pager.c 196b112bb00473f719f49fa777f609c135fdd886
|
||||
F src/pager.h 13fd98ed10e7d23b23721dd2eafa474c26c9a234
|
||||
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
|
||||
F src/pcache.c b9d52e9f844d91c27c161279234f273fc02abc71
|
||||
F src/pcache.h c770382f9fae4ca5025c5523bd0aa13cd6ddc6f8
|
||||
F src/pcache.c e9246c20744e13268e7e02230446bc748c5cc470
|
||||
F src/pcache.h f8a98a37dd4f7c8bb4ffbdbd6284457c6b78b16e
|
||||
F src/pcache1.c 0ac7b63db83a705787f4ababf1e4cff27b5f8064
|
||||
F src/pragma.c 65d1d63d64f8b7350f28d5ee6d40f7985deccdfe
|
||||
F src/prepare.c ec4989f7f480544bdc4192fe663470d2a2d7d61e
|
||||
@@ -182,7 +182,7 @@ F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809
|
||||
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
||||
F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6
|
||||
F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8
|
||||
F src/sqlite.h.in 557f4113a649f15d13e566aaa85820509b4daa52
|
||||
F src/sqlite.h.in e08f84145c049bef7a235221f1b5dc65a79db9ad
|
||||
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
|
||||
F src/sqliteInt.h f87f241b9821a9d466c2711b7345d30ef3624249
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
@@ -699,7 +699,7 @@ F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
|
||||
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
|
||||
F test/superlock.test 7b1167925e9d30a5d1f0701d24812fdda42c3a86
|
||||
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
|
||||
F test/syscall.test 2a922050dbee032f587249b070fb42692f5e1e22
|
||||
F test/syscall.test e97f53ebfcc93fe89c61e1a3b5f120f28ec671b7
|
||||
F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f
|
||||
F test/table.test a59d985ca366e39b17b175f387f9d5db5a18d4e2
|
||||
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
|
||||
@@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
|
||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||
P ceee03c79a55ea39866758aa76b78b10e5f4246d
|
||||
R d08ae8acf53f2cb149aeb898f50b49c8
|
||||
P 09be42d5fa7ef692428579d4d8d48b3316190945
|
||||
R befae33617c94c7a45bbbb00f51b97b6
|
||||
U drh
|
||||
Z af6f24cf5b51e20dd59385851602a05e
|
||||
Z ea236fcfb430914e9125ff2cd702c553
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
9f839ac05a9f3cfe587d2ccdccd50dac41baedbe
|
||||
638a39bbaa034a08d73459a36bbe14b76b34189f
|
||||
+74
-47
@@ -728,6 +728,26 @@ int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Set up the correct data pointers for a MemPage
|
||||
*/
|
||||
static u8 *btreeGetData(MemPage *pPage){
|
||||
pPage->aData = sqlite3PagerGetData(pPage->pDbPage);
|
||||
pPage->aDataEnd = &pPage->aData[pPage->pBt->usableSize];
|
||||
pPage->aCellIdx = &pPage->aData[pPage->cellOffset];
|
||||
return pPage->aData;
|
||||
}
|
||||
|
||||
/*
|
||||
** Make a btree page is writable.
|
||||
*/
|
||||
static int btreeMakePageWriteable(MemPage *pPage){
|
||||
int rc;
|
||||
rc = sqlite3PagerWrite(pPage->pDbPage);
|
||||
btreeGetData(pPage);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
/*
|
||||
** Given a page number of a regular database page, return the page
|
||||
@@ -797,6 +817,7 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){
|
||||
if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
|
||||
TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent));
|
||||
*pRC= rc = sqlite3PagerWrite(pDbPage);
|
||||
pPtrmap = sqlite3PagerGetData(pDbPage);
|
||||
if( rc==SQLITE_OK ){
|
||||
pPtrmap[offset] = eType;
|
||||
put4byte(&pPtrmap[offset+1], parent);
|
||||
@@ -1545,7 +1566,7 @@ static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){
|
||||
** If the noContent flag is set, it means that we do not care about
|
||||
** the content of the page at this time. So do not go to the disk
|
||||
** to fetch the content. Just fill in the content with zeros for now.
|
||||
** If in the future we call sqlite3PagerWrite() on this page, that
|
||||
** If in the future we call btreeMakePageWriteable() on this page, that
|
||||
** means we have started to be concerned about content and the disk
|
||||
** read should occur at that point.
|
||||
*/
|
||||
@@ -1635,7 +1656,7 @@ static void releasePage(MemPage *pPage){
|
||||
assert( pPage->aData );
|
||||
assert( pPage->pBt );
|
||||
assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
|
||||
assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
|
||||
/* assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); */
|
||||
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
|
||||
sqlite3PagerUnref(pPage->pDbPage);
|
||||
}
|
||||
@@ -2310,6 +2331,7 @@ static int lockBtree(BtShared *pBt){
|
||||
int nPage; /* Number of pages in the database */
|
||||
int nPageFile = 0; /* Number of pages in the database file */
|
||||
int nPageHeader; /* Number of pages in the database according to hdr */
|
||||
u8 *page1; /* Content of page 1 */
|
||||
|
||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||
assert( pBt->pPage1==0 );
|
||||
@@ -2321,15 +2343,15 @@ static int lockBtree(BtShared *pBt){
|
||||
/* Do some checking to help insure the file we opened really is
|
||||
** a valid database file.
|
||||
*/
|
||||
nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData);
|
||||
page1 = btreeGetData(pPage1);
|
||||
nPage = nPageHeader = get4byte(&page1[28]);
|
||||
sqlite3PagerPagecount(pBt->pPager, &nPageFile);
|
||||
if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){
|
||||
if( nPage==0 || memcmp(24+page1, 92+page1, 4)!=0 ){
|
||||
nPage = nPageFile;
|
||||
}
|
||||
if( nPage>0 ){
|
||||
u32 pageSize;
|
||||
u32 usableSize;
|
||||
u8 *page1 = pPage1->aData;
|
||||
rc = SQLITE_NOTADB;
|
||||
if( memcmp(page1, zMagicHeader, 16)!=0 ){
|
||||
goto page1_init_failed;
|
||||
@@ -2482,9 +2504,9 @@ static int newDatabase(BtShared *pBt){
|
||||
}
|
||||
pP1 = pBt->pPage1;
|
||||
assert( pP1!=0 );
|
||||
rc = sqlite3PagerWrite(pP1->pDbPage);
|
||||
rc = btreeMakePageWriteable(pP1);
|
||||
if( rc ) return rc;
|
||||
data = pP1->aData;
|
||||
data = btreeGetData(pP1);
|
||||
memcpy(data, zMagicHeader, sizeof(zMagicHeader));
|
||||
assert( sizeof(zMagicHeader)==16 );
|
||||
data[16] = (u8)((pBt->pageSize>>8)&0xff);
|
||||
@@ -2654,8 +2676,9 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
|
||||
** re-read the database size from page 1 if a savepoint or transaction
|
||||
** rollback occurs within the transaction.
|
||||
*/
|
||||
btreeGetData(pPage1);
|
||||
if( pBt->nPage!=get4byte(&pPage1->aData[28]) ){
|
||||
rc = sqlite3PagerWrite(pPage1->pDbPage);
|
||||
rc = btreeMakePageWriteable(pPage1);
|
||||
if( rc==SQLITE_OK ){
|
||||
put4byte(&pPage1->aData[28], pBt->nPage);
|
||||
}
|
||||
@@ -2854,7 +2877,7 @@ static int relocatePage(
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
rc = sqlite3PagerWrite(pPtrPage->pDbPage);
|
||||
rc = btreeMakePageWriteable(pPtrPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
releasePage(pPtrPage);
|
||||
return rc;
|
||||
@@ -2900,6 +2923,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
|
||||
u8 eType;
|
||||
Pgno iPtrPage;
|
||||
|
||||
btreeGetData(pBt->pPage1);
|
||||
nFreeList = get4byte(&pBt->pPage1->aData[36]);
|
||||
if( nFreeList==0 ){
|
||||
return SQLITE_DONE;
|
||||
@@ -2956,7 +2980,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
|
||||
}while( nFin!=0 && iFreePg>nFin );
|
||||
assert( iFreePg<iLastPg );
|
||||
|
||||
rc = sqlite3PagerWrite(pLastPg->pDbPage);
|
||||
rc = btreeMakePageWriteable(pLastPg);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, nFin!=0);
|
||||
}
|
||||
@@ -2976,7 +3000,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
rc = sqlite3PagerWrite(pPg->pDbPage);
|
||||
rc = btreeMakePageWriteable(pPg);
|
||||
releasePage(pPg);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
@@ -3010,7 +3034,7 @@ int sqlite3BtreeIncrVacuum(Btree *p){
|
||||
invalidateAllOverflowCache(pBt);
|
||||
rc = incrVacuumStep(pBt, 0, btreePagecount(pBt));
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
|
||||
rc = btreeMakePageWriteable(pBt->pPage1);
|
||||
put4byte(&pBt->pPage1->aData[28], pBt->nPage);
|
||||
}
|
||||
}
|
||||
@@ -3052,6 +3076,7 @@ static int autoVacuumCommit(BtShared *pBt){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
|
||||
btreeGetData(pBt->pPage1);
|
||||
nFree = get4byte(&pBt->pPage1->aData[36]);
|
||||
nEntry = pBt->usableSize/5;
|
||||
nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+nEntry)/nEntry;
|
||||
@@ -3068,7 +3093,7 @@ static int autoVacuumCommit(BtShared *pBt){
|
||||
rc = incrVacuumStep(pBt, nFin, iFree);
|
||||
}
|
||||
if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
|
||||
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
|
||||
rc = btreeMakePageWriteable(pBt->pPage1);
|
||||
put4byte(&pBt->pPage1->aData[32], 0);
|
||||
put4byte(&pBt->pPage1->aData[36], 0);
|
||||
put4byte(&pBt->pPage1->aData[28], nFin);
|
||||
@@ -3411,7 +3436,7 @@ int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){
|
||||
if( rc==SQLITE_OK ){
|
||||
if( iSavepoint<0 && pBt->initiallyEmpty ) pBt->nPage = 0;
|
||||
rc = newDatabase(pBt);
|
||||
pBt->nPage = get4byte(28 + pBt->pPage1->aData);
|
||||
pBt->nPage = get4byte(28 + btreeGetData(pBt->pPage1));
|
||||
|
||||
/* The database size was written into the offset 28 of the header
|
||||
** when the transaction started, so we know that the value at offset
|
||||
@@ -3848,7 +3873,7 @@ static int accessPayload(
|
||||
a = pCur->info.nLocal - offset;
|
||||
}
|
||||
if( eOp ){
|
||||
if( (rc = sqlite3PagerWrite(pPage->pDbPage))!=SQLITE_OK ) return rc;
|
||||
if( (rc = btreeMakePageWriteable(pPage))!=SQLITE_OK ) return rc;
|
||||
getCellInfo(pCur);
|
||||
aPayload = pCur->info.pCell + pCur->info.nHeader;
|
||||
memcpy(aPayload+offset, pBuf, a);
|
||||
@@ -3950,7 +3975,7 @@ static int accessPayload(
|
||||
&& offset==0 /* (2) */
|
||||
&& pBt->inTransaction==TRANS_READ /* (4) */
|
||||
&& (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */
|
||||
&& pBt->pPage1->aData[19]==0x01 /* (5) */
|
||||
&& btreeGetData(pBt->pPage1)[19]==0x01 /* (5) */
|
||||
){
|
||||
u8 aSave[4];
|
||||
u8 *aWrite = &pBuf[-4];
|
||||
@@ -4776,7 +4801,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
||||
/*
|
||||
** Allocate a new page from the database file.
|
||||
**
|
||||
** The new page is marked as dirty. (In other words, sqlite3PagerWrite()
|
||||
** The new page is marked as dirty. (In other words, btreeMakePageWriteable()
|
||||
** has already been called on the new page.) The new page has also
|
||||
** been referenced and the calling routine is responsible for calling
|
||||
** sqlite3PagerUnref() on the new page when it is done.
|
||||
@@ -4812,7 +4837,7 @@ static int allocateBtreePage(
|
||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||
pPage1 = pBt->pPage1;
|
||||
mxPage = btreePagecount(pBt);
|
||||
n = get4byte(&pPage1->aData[36]);
|
||||
n = get4byte(&btreeGetData(pPage1)[36]);
|
||||
testcase( n==mxPage-1 );
|
||||
if( n>=mxPage ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
@@ -4843,7 +4868,7 @@ static int allocateBtreePage(
|
||||
/* Decrement the free-list count by 1. Set iTrunk to the index of the
|
||||
** first free-list trunk page. iPrevTrunk is initially 1.
|
||||
*/
|
||||
rc = sqlite3PagerWrite(pPage1->pDbPage);
|
||||
rc = btreeMakePageWriteable(pPage1);
|
||||
if( rc ) return rc;
|
||||
put4byte(&pPage1->aData[36], n-1);
|
||||
|
||||
@@ -4877,7 +4902,7 @@ static int allocateBtreePage(
|
||||
** So extract the trunk page itself and use it as the newly
|
||||
** allocated page */
|
||||
assert( pPrevTrunk==0 );
|
||||
rc = sqlite3PagerWrite(pTrunk->pDbPage);
|
||||
rc = btreeMakePageWriteable(pTrunk);
|
||||
if( rc ){
|
||||
goto end_allocate_page;
|
||||
}
|
||||
@@ -4898,7 +4923,7 @@ static int allocateBtreePage(
|
||||
assert( *pPgno==iTrunk );
|
||||
*ppPage = pTrunk;
|
||||
searchList = 0;
|
||||
rc = sqlite3PagerWrite(pTrunk->pDbPage);
|
||||
rc = btreeMakePageWriteable(pTrunk);
|
||||
if( rc ){
|
||||
goto end_allocate_page;
|
||||
}
|
||||
@@ -4906,7 +4931,7 @@ static int allocateBtreePage(
|
||||
if( !pPrevTrunk ){
|
||||
memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
|
||||
}else{
|
||||
rc = sqlite3PagerWrite(pPrevTrunk->pDbPage);
|
||||
rc = btreeMakePageWriteable(pPrevTrunk);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto end_allocate_page;
|
||||
}
|
||||
@@ -4928,7 +4953,7 @@ static int allocateBtreePage(
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto end_allocate_page;
|
||||
}
|
||||
rc = sqlite3PagerWrite(pNewTrunk->pDbPage);
|
||||
rc = btreeMakePageWriteable(pNewTrunk);
|
||||
if( rc!=SQLITE_OK ){
|
||||
releasePage(pNewTrunk);
|
||||
goto end_allocate_page;
|
||||
@@ -4941,7 +4966,7 @@ static int allocateBtreePage(
|
||||
assert( sqlite3PagerIswriteable(pPage1->pDbPage) );
|
||||
put4byte(&pPage1->aData[32], iNewTrunk);
|
||||
}else{
|
||||
rc = sqlite3PagerWrite(pPrevTrunk->pDbPage);
|
||||
rc = btreeMakePageWriteable(pPrevTrunk);
|
||||
if( rc ){
|
||||
goto end_allocate_page;
|
||||
}
|
||||
@@ -4985,8 +5010,9 @@ static int allocateBtreePage(
|
||||
TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
|
||||
": %d more free pages\n",
|
||||
*pPgno, closest+1, k, pTrunk->pgno, n-1));
|
||||
rc = sqlite3PagerWrite(pTrunk->pDbPage);
|
||||
rc = btreeMakePageWriteable(pTrunk);
|
||||
if( rc ) goto end_allocate_page;
|
||||
aData = pTrunk->aData;
|
||||
if( closest<k-1 ){
|
||||
memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
|
||||
}
|
||||
@@ -4994,7 +5020,7 @@ static int allocateBtreePage(
|
||||
noContent = !btreeGetHasContent(pBt, *pPgno);
|
||||
rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
|
||||
rc = btreeMakePageWriteable(*ppPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
releasePage(*ppPage);
|
||||
}
|
||||
@@ -5008,7 +5034,7 @@ static int allocateBtreePage(
|
||||
}else{
|
||||
/* There are no pages on the freelist, so create a new page at the
|
||||
** end of the file */
|
||||
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
|
||||
rc = btreeMakePageWriteable(pBt->pPage1);
|
||||
if( rc ) return rc;
|
||||
pBt->nPage++;
|
||||
if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++;
|
||||
@@ -5024,7 +5050,7 @@ static int allocateBtreePage(
|
||||
assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
|
||||
rc = btreeGetPage(pBt, pBt->nPage, &pPg, 1);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerWrite(pPg->pDbPage);
|
||||
rc = btreeMakePageWriteable(pPg);
|
||||
releasePage(pPg);
|
||||
}
|
||||
if( rc ) return rc;
|
||||
@@ -5038,7 +5064,7 @@ static int allocateBtreePage(
|
||||
assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
|
||||
rc = btreeGetPage(pBt, *pPgno, ppPage, 1);
|
||||
if( rc ) return rc;
|
||||
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
|
||||
rc = btreeMakePageWriteable(*ppPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
releasePage(*ppPage);
|
||||
}
|
||||
@@ -5095,7 +5121,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
|
||||
}
|
||||
|
||||
/* Increment the free page count on pPage1 */
|
||||
rc = sqlite3PagerWrite(pPage1->pDbPage);
|
||||
rc = btreeMakePageWriteable(pPage1);
|
||||
if( rc ) goto freepage_out;
|
||||
nFree = get4byte(&pPage1->aData[36]);
|
||||
put4byte(&pPage1->aData[36], nFree+1);
|
||||
@@ -5105,7 +5131,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
|
||||
** always fully overwrite deleted information with zeros.
|
||||
*/
|
||||
if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) )
|
||||
|| ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0)
|
||||
|| ((rc = btreeMakePageWriteable(pPage))!=0)
|
||||
){
|
||||
goto freepage_out;
|
||||
}
|
||||
@@ -5157,7 +5183,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
|
||||
** to 3.6.0 or later) we should consider fixing the conditional above
|
||||
** to read "usableSize/4-2" instead of "usableSize/4-8".
|
||||
*/
|
||||
rc = sqlite3PagerWrite(pTrunk->pDbPage);
|
||||
rc = btreeMakePageWriteable(pTrunk);
|
||||
if( rc==SQLITE_OK ){
|
||||
put4byte(&pTrunk->aData[4], nLeaf+1);
|
||||
put4byte(&pTrunk->aData[8+nLeaf*4], iPage);
|
||||
@@ -5180,7 +5206,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
|
||||
if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){
|
||||
goto freepage_out;
|
||||
}
|
||||
rc = sqlite3PagerWrite(pPage->pDbPage);
|
||||
rc = btreeMakePageWriteable(pPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto freepage_out;
|
||||
}
|
||||
@@ -5540,7 +5566,7 @@ static void insertCell(
|
||||
pPage->aOvfl[j].pCell = pCell;
|
||||
pPage->aOvfl[j].idx = (u16)i;
|
||||
}else{
|
||||
int rc = sqlite3PagerWrite(pPage->pDbPage);
|
||||
int rc = btreeMakePageWriteable(pPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
*pRC = rc;
|
||||
return;
|
||||
@@ -6209,7 +6235,7 @@ static int balance_nonroot(
|
||||
if( i<nOld ){
|
||||
pNew = apNew[i] = apOld[i];
|
||||
apOld[i] = 0;
|
||||
rc = sqlite3PagerWrite(pNew->pDbPage);
|
||||
rc = btreeMakePageWriteable(pNew);
|
||||
nNew++;
|
||||
if( rc ) goto balance_cleanup;
|
||||
}else{
|
||||
@@ -6538,7 +6564,7 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){
|
||||
** page that will become the new right-child of pPage. Copy the contents
|
||||
** of the node stored on pRoot into the new child page.
|
||||
*/
|
||||
rc = sqlite3PagerWrite(pRoot->pDbPage);
|
||||
rc = btreeMakePageWriteable(pRoot);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0);
|
||||
copyNodeContent(pRoot, pChild, &rc);
|
||||
@@ -6616,7 +6642,7 @@ static int balance(BtCursor *pCur){
|
||||
MemPage * const pParent = pCur->apPage[iPage-1];
|
||||
int const iIdx = pCur->aiIdx[iPage-1];
|
||||
|
||||
rc = sqlite3PagerWrite(pParent->pDbPage);
|
||||
rc = btreeMakePageWriteable(pParent);
|
||||
if( rc==SQLITE_OK ){
|
||||
#ifndef SQLITE_OMIT_QUICKBALANCE
|
||||
if( pPage->hasData
|
||||
@@ -6793,7 +6819,7 @@ int sqlite3BtreeInsert(
|
||||
if( loc==0 ){
|
||||
u16 szOld;
|
||||
assert( idx<pPage->nCell );
|
||||
rc = sqlite3PagerWrite(pPage->pDbPage);
|
||||
rc = btreeMakePageWriteable(pPage);
|
||||
if( rc ){
|
||||
goto end_insert;
|
||||
}
|
||||
@@ -6909,7 +6935,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){
|
||||
*/
|
||||
rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
|
||||
if( rc ) return rc;
|
||||
rc = sqlite3PagerWrite(pPage->pDbPage);
|
||||
rc = btreeMakePageWriteable(pPage);
|
||||
if( rc ) return rc;
|
||||
rc = clearCell(pPage, pCell);
|
||||
dropCell(pPage, iCellIdx, cellSizePtr(pPage, pCell), &rc);
|
||||
@@ -6933,7 +6959,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){
|
||||
allocateTempSpace(pBt);
|
||||
pTmp = pBt->pTmpSpace;
|
||||
|
||||
rc = sqlite3PagerWrite(pLeaf->pDbPage);
|
||||
rc = btreeMakePageWriteable(pLeaf);
|
||||
insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
|
||||
dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
|
||||
if( rc ) return rc;
|
||||
@@ -7070,7 +7096,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
rc = sqlite3PagerWrite(pRoot->pDbPage);
|
||||
rc = btreeMakePageWriteable(pRoot);
|
||||
if( rc!=SQLITE_OK ){
|
||||
releasePage(pRoot);
|
||||
return rc;
|
||||
@@ -7162,7 +7188,7 @@ static int clearDatabasePage(
|
||||
}
|
||||
if( freePageFlag ){
|
||||
freePage(pPage, &rc);
|
||||
}else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){
|
||||
}else if( (rc = btreeMakePageWriteable(pPage))==0 ){
|
||||
zeroPage(pPage, pPage->aData[0] | PTF_LEAF);
|
||||
}
|
||||
|
||||
@@ -7357,7 +7383,7 @@ void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
|
||||
assert( pBt->pPage1 );
|
||||
assert( idx>=0 && idx<=15 );
|
||||
|
||||
*pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]);
|
||||
*pMeta = get4byte(&btreeGetData(pBt->pPage1)[36 + idx*4]);
|
||||
|
||||
/* If auto-vacuum is disabled in this build and this is an auto-vacuum
|
||||
** database, mark the database as read-only. */
|
||||
@@ -7379,7 +7405,7 @@ int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
|
||||
sqlite3BtreeEnter(p);
|
||||
assert( p->inTrans==TRANS_WRITE );
|
||||
assert( pBt->pPage1!=0 );
|
||||
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
|
||||
rc = btreeMakePageWriteable(pBt->pPage1);
|
||||
if( rc==SQLITE_OK ){
|
||||
put4byte(&pBt->pPage1->aData[36 + idx*4], iMeta);
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
@@ -7917,6 +7943,7 @@ char *sqlite3BtreeIntegrityCheck(
|
||||
|
||||
/* Check the integrity of the freelist
|
||||
*/
|
||||
btreeGetData(pBt->pPage1);
|
||||
checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
|
||||
get4byte(&pBt->pPage1->aData[36]), "Main freelist: ");
|
||||
|
||||
@@ -8204,13 +8231,13 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
|
||||
|
||||
rc = sqlite3BtreeBeginTrans(pBtree, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
u8 *aData = pBt->pPage1->aData;
|
||||
u8 *aData = btreeGetData(pBt->pPage1);
|
||||
if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){
|
||||
rc = sqlite3BtreeBeginTrans(pBtree, 2);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
|
||||
rc = btreeMakePageWriteable(pBt->pPage1);
|
||||
if( rc==SQLITE_OK ){
|
||||
aData = pBt->pPage1->aData;
|
||||
aData = btreeGetData(pBt->pPage1);
|
||||
aData[18] = (u8)iVersion;
|
||||
aData[19] = (u8)iVersion;
|
||||
}
|
||||
|
||||
@@ -199,6 +199,52 @@ int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Attempt to map all or part of a file into memory. VFSes are not
|
||||
** required to implement this. The VFS might be an older version (less then
|
||||
** 3) that does not have an xMap pointer. Or the xMap pointer might be NULL.
|
||||
*/
|
||||
int sqlite3OsMap(
|
||||
sqlite3_file *pFile, /* The file to be mapped into memory */
|
||||
sqlite3_int64 ofst, /* Index of the first byte to map */
|
||||
sqlite3_int64 len, /* Number of bytes to be mapped */
|
||||
int mmapFlags, /* Map control flags */
|
||||
void **ppMemObj, /* Write a mapping object here */
|
||||
void **ppMem /* Write the start of the mapped file here */
|
||||
){
|
||||
int rc;
|
||||
|
||||
/* The current implementation only does read-only mmap. This could change
|
||||
** in the future. */
|
||||
assert( mmapFlags==SQLITE_OPEN_READONLY );
|
||||
|
||||
/* The current implementation currently only maps the whole file. This
|
||||
** could change in the future. */
|
||||
assert( ofst==0 );
|
||||
|
||||
if( pFile->pMethods==0 || pFile->pMethods->iVersion<3
|
||||
|| pFile->pMethods->xMap==0 ){
|
||||
*ppMemObj = 0;
|
||||
*ppMem = 0;
|
||||
rc = SQLITE_CANTOPEN;
|
||||
}else{
|
||||
rc = pFile->pMethods->xMap(pFile, ofst, len, mmapFlags, ppMemObj, ppMem);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Undo a mapping.
|
||||
**
|
||||
** The pMemObj parameter will have been obtained by a prior call to
|
||||
** sqlite3OsMap(). So if pMemObj is not NULL, we know that the current
|
||||
** VFS does support xMap and xUnmap.
|
||||
*/
|
||||
int sqlite3OsUnmap(sqlite3_file *pFile, void *pMemObj){
|
||||
int rc = SQLITE_OK;
|
||||
if( pMemObj ) rc = pFile->pMethods->xUnmap(pFile, pMemObj);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int sqlite3OsOpenMalloc(
|
||||
sqlite3_vfs *pVfs,
|
||||
const char *zFile,
|
||||
|
||||
@@ -251,6 +251,8 @@ int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **);
|
||||
int sqlite3OsShmLock(sqlite3_file *id, int, int, int);
|
||||
void sqlite3OsShmBarrier(sqlite3_file *id);
|
||||
int sqlite3OsShmUnmap(sqlite3_file *id, int);
|
||||
int sqlite3OsMap(sqlite3_file*,sqlite3_int64,sqlite3_int64,int,void**,void**);
|
||||
int sqlite3OsUnmap(sqlite3_file*,void*);
|
||||
|
||||
/*
|
||||
** Functions for accessing sqlite3_vfs methods
|
||||
|
||||
+88
-23
@@ -119,9 +119,7 @@
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||
# include <sys/ioctl.h>
|
||||
@@ -413,6 +411,14 @@ static struct unix_syscall {
|
||||
{ "rmdir", (sqlite3_syscall_ptr)rmdir, 0 },
|
||||
#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
|
||||
|
||||
{ "mmap", (sqlite3_syscall_ptr)mmap, 0 },
|
||||
#define osMmap ((int(*)(void*,size_t,int,int,int,off_t))aSyscall[20].pCurrent)
|
||||
|
||||
{ "munmap", (sqlite3_syscall_ptr)munmap, 0 },
|
||||
#define osMunmap ((int(*)(void*,size_t))aSyscall[21].pCurrent)
|
||||
|
||||
|
||||
|
||||
}; /* End of the overrideable system calls */
|
||||
|
||||
/*
|
||||
@@ -4229,6 +4235,63 @@ static int unixShmUnmap(
|
||||
# define unixShmUnmap 0
|
||||
#endif /* #ifndef SQLITE_OMIT_WAL */
|
||||
|
||||
/*
|
||||
** An object used to record enough information about a file mapping to
|
||||
** undo that mapping.
|
||||
*/
|
||||
struct unixMapping {
|
||||
sqlite3_int64 len;
|
||||
void *p;
|
||||
};
|
||||
|
||||
/*
|
||||
** Try to map some or all of a file into memory
|
||||
*/
|
||||
static int unixMap(
|
||||
sqlite3_file *pFile, /* File to be mapped */
|
||||
sqlite3_int64 ofst, /* Offset of start of section to be mapped */
|
||||
sqlite3_int64 len, /* Length of the section to be mapped */
|
||||
int mmapFlags, /* Flags controlling the mapping */
|
||||
void **ppMapObj, /* Write here an object to undo the mapping */
|
||||
void **ppMem /* Write here a pointer to the mapped file */
|
||||
){
|
||||
struct unixMapping *pNew;
|
||||
unixFile *pUFile = (unixFile*)pFile;
|
||||
|
||||
assert( mmapFlags==SQLITE_OPEN_READONLY );
|
||||
sqlite3BeginBenignMalloc();
|
||||
pNew = sqlite3_malloc( sizeof(*pNew) );
|
||||
sqlite3EndBenignMalloc();
|
||||
if( pNew==0 ){
|
||||
*ppMapObj = 0;
|
||||
*ppMem = 0;
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
pNew->len = len;
|
||||
pNew->p = *ppMem = mmap(0, len, PROT_READ, MAP_SHARED, pUFile->h, 0);
|
||||
if( pNew->p==0 ){
|
||||
sqlite3_free(pNew);
|
||||
return SQLITE_CANTOPEN;
|
||||
}else{
|
||||
*ppMapObj = pNew;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Undo a prior memory mapping.
|
||||
*/
|
||||
static int unixUnmap(
|
||||
sqlite3_file *pFile,
|
||||
void *pMapObj
|
||||
){
|
||||
struct unixMapping *pMap = (struct unixMapping*)pMapObj;
|
||||
assert( pMap!=0 );
|
||||
munmap(pMap->p, pMap->len);
|
||||
sqlite3_free(pMap);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Here ends the implementation of all sqlite3_file methods.
|
||||
**
|
||||
@@ -4269,9 +4332,9 @@ static int unixShmUnmap(
|
||||
** * An I/O method finder function called FINDER that returns a pointer
|
||||
** to the METHOD object in the previous bullet.
|
||||
*/
|
||||
#define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK) \
|
||||
#define IOMETHODS(FINDER, METHOD, CLOSE, LOCK, UNLOCK, CKLOCK, SHMMAP) \
|
||||
static const sqlite3_io_methods METHOD = { \
|
||||
VERSION, /* iVersion */ \
|
||||
3, /* iVersion */ \
|
||||
CLOSE, /* xClose */ \
|
||||
unixRead, /* xRead */ \
|
||||
unixWrite, /* xWrite */ \
|
||||
@@ -4284,10 +4347,12 @@ static const sqlite3_io_methods METHOD = { \
|
||||
unixFileControl, /* xFileControl */ \
|
||||
unixSectorSize, /* xSectorSize */ \
|
||||
unixDeviceCharacteristics, /* xDeviceCapabilities */ \
|
||||
unixShmMap, /* xShmMap */ \
|
||||
SHMMAP, /* xShmMap */ \
|
||||
unixShmLock, /* xShmLock */ \
|
||||
unixShmBarrier, /* xShmBarrier */ \
|
||||
unixShmUnmap /* xShmUnmap */ \
|
||||
unixShmUnmap, /* xShmUnmap */ \
|
||||
unixMap, /* xMap */ \
|
||||
unixUnmap /* xUnmap */ \
|
||||
}; \
|
||||
static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \
|
||||
UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \
|
||||
@@ -4304,40 +4369,40 @@ static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p) \
|
||||
IOMETHODS(
|
||||
posixIoFinder, /* Finder function name */
|
||||
posixIoMethods, /* sqlite3_io_methods object name */
|
||||
2, /* shared memory is enabled */
|
||||
unixClose, /* xClose method */
|
||||
unixLock, /* xLock method */
|
||||
unixUnlock, /* xUnlock method */
|
||||
unixCheckReservedLock /* xCheckReservedLock method */
|
||||
unixCheckReservedLock, /* xCheckReservedLock method */
|
||||
unixShmMap /* Shared memory enabled */
|
||||
)
|
||||
IOMETHODS(
|
||||
nolockIoFinder, /* Finder function name */
|
||||
nolockIoMethods, /* sqlite3_io_methods object name */
|
||||
1, /* shared memory is disabled */
|
||||
nolockClose, /* xClose method */
|
||||
nolockLock, /* xLock method */
|
||||
nolockUnlock, /* xUnlock method */
|
||||
nolockCheckReservedLock /* xCheckReservedLock method */
|
||||
nolockCheckReservedLock, /* xCheckReservedLock method */
|
||||
0 /* Shared memory disabled */
|
||||
)
|
||||
IOMETHODS(
|
||||
dotlockIoFinder, /* Finder function name */
|
||||
dotlockIoMethods, /* sqlite3_io_methods object name */
|
||||
1, /* shared memory is disabled */
|
||||
dotlockClose, /* xClose method */
|
||||
dotlockLock, /* xLock method */
|
||||
dotlockUnlock, /* xUnlock method */
|
||||
dotlockCheckReservedLock /* xCheckReservedLock method */
|
||||
dotlockCheckReservedLock, /* xCheckReservedLock method */
|
||||
0 /* Shared memory disabled */
|
||||
)
|
||||
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
|
||||
IOMETHODS(
|
||||
flockIoFinder, /* Finder function name */
|
||||
flockIoMethods, /* sqlite3_io_methods object name */
|
||||
1, /* shared memory is disabled */
|
||||
flockClose, /* xClose method */
|
||||
flockLock, /* xLock method */
|
||||
flockUnlock, /* xUnlock method */
|
||||
flockCheckReservedLock /* xCheckReservedLock method */
|
||||
flockCheckReservedLock, /* xCheckReservedLock method */
|
||||
0 /* Shared memory disabled */
|
||||
)
|
||||
#endif
|
||||
|
||||
@@ -4345,11 +4410,11 @@ IOMETHODS(
|
||||
IOMETHODS(
|
||||
semIoFinder, /* Finder function name */
|
||||
semIoMethods, /* sqlite3_io_methods object name */
|
||||
1, /* shared memory is disabled */
|
||||
semClose, /* xClose method */
|
||||
semLock, /* xLock method */
|
||||
semUnlock, /* xUnlock method */
|
||||
semCheckReservedLock /* xCheckReservedLock method */
|
||||
semCheckReservedLock, /* xCheckReservedLock method */
|
||||
0 /* Shared memory disabled */
|
||||
)
|
||||
#endif
|
||||
|
||||
@@ -4357,11 +4422,11 @@ IOMETHODS(
|
||||
IOMETHODS(
|
||||
afpIoFinder, /* Finder function name */
|
||||
afpIoMethods, /* sqlite3_io_methods object name */
|
||||
1, /* shared memory is disabled */
|
||||
afpClose, /* xClose method */
|
||||
afpLock, /* xLock method */
|
||||
afpUnlock, /* xUnlock method */
|
||||
afpCheckReservedLock /* xCheckReservedLock method */
|
||||
afpCheckReservedLock, /* xCheckReservedLock method */
|
||||
0 /* Shared memory disabled */
|
||||
)
|
||||
#endif
|
||||
|
||||
@@ -4382,11 +4447,11 @@ static int proxyCheckReservedLock(sqlite3_file*, int*);
|
||||
IOMETHODS(
|
||||
proxyIoFinder, /* Finder function name */
|
||||
proxyIoMethods, /* sqlite3_io_methods object name */
|
||||
1, /* shared memory is disabled */
|
||||
proxyClose, /* xClose method */
|
||||
proxyLock, /* xLock method */
|
||||
proxyUnlock, /* xUnlock method */
|
||||
proxyCheckReservedLock /* xCheckReservedLock method */
|
||||
proxyCheckReservedLock, /* xCheckReservedLock method */
|
||||
0 /* Shared memory disabled */
|
||||
)
|
||||
#endif
|
||||
|
||||
@@ -4395,11 +4460,11 @@ IOMETHODS(
|
||||
IOMETHODS(
|
||||
nfsIoFinder, /* Finder function name */
|
||||
nfsIoMethods, /* sqlite3_io_methods object name */
|
||||
1, /* shared memory is disabled */
|
||||
unixClose, /* xClose method */
|
||||
unixLock, /* xLock method */
|
||||
nfsUnlock, /* xUnlock method */
|
||||
unixCheckReservedLock /* xCheckReservedLock method */
|
||||
unixCheckReservedLock, /* xCheckReservedLock method */
|
||||
0 /* Shared memory disabled */
|
||||
)
|
||||
#endif
|
||||
|
||||
@@ -6771,7 +6836,7 @@ int sqlite3_os_init(void){
|
||||
|
||||
/* Double-check that the aSyscall[] array has been constructed
|
||||
** correctly. See ticket [bb3a86e890c8e96ab] */
|
||||
assert( ArraySize(aSyscall)==20 );
|
||||
assert( ArraySize(aSyscall)==22 );
|
||||
|
||||
/* Register all VFSes defined in the aVfs[] array */
|
||||
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
|
||||
|
||||
+51
-14
@@ -655,6 +655,9 @@ struct Pager {
|
||||
PagerSavepoint *aSavepoint; /* Array of active savepoints */
|
||||
int nSavepoint; /* Number of elements in aSavepoint[] */
|
||||
char dbFileVers[16]; /* Changes whenever database file changes */
|
||||
u8 *aFileContent; /* File mapped into memory */
|
||||
sqlite3_int64 nFileContent; /* Bytes of memory mapped into aFileContent */
|
||||
void *pMapObject; /* Used to unmap the file */
|
||||
/*
|
||||
** End of the routinely-changing class members
|
||||
***************************************************************************/
|
||||
@@ -1723,6 +1726,7 @@ static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){
|
||||
** is opened (by this or by any other connection).
|
||||
*/
|
||||
static void pager_unlock(Pager *pPager){
|
||||
PgHdr *pPg;
|
||||
|
||||
assert( pPager->eState==PAGER_READER
|
||||
|| pPager->eState==PAGER_OPEN
|
||||
@@ -1793,6 +1797,20 @@ static void pager_unlock(Pager *pPager){
|
||||
pPager->journalOff = 0;
|
||||
pPager->journalHdr = 0;
|
||||
pPager->setMaster = 0;
|
||||
|
||||
pPg = 0;
|
||||
sqlite3PcacheFetch(pPager->pPCache, 1, 0, &pPg);
|
||||
if( pPg ){
|
||||
/* assert( sqlite3PcachePagecount(pPager->pPCache)==1 ); */
|
||||
pPg->pData = pPg->pBuf;
|
||||
sqlite3PcacheRelease(pPg);
|
||||
}else{
|
||||
/*assert( sqlite3PcachePagecount(pPager->pPCache)==0 );*/
|
||||
}
|
||||
sqlite3OsUnmap(pPager->fd, pPager->pMapObject);
|
||||
pPager->pMapObject = 0;
|
||||
pPager->aFileContent = 0;
|
||||
pPager->nFileContent = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2800,22 +2818,21 @@ static int readDbPage(PgHdr *pPg){
|
||||
|
||||
assert( pPager->eState>=PAGER_READER && !MEMDB );
|
||||
assert( isOpen(pPager->fd) );
|
||||
|
||||
if( NEVER(!isOpen(pPager->fd)) ){
|
||||
assert( pPager->tempFile );
|
||||
memset(pPg->pData, 0, pPager->pageSize);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
assert( pPg->pBuf==pPg->pData );
|
||||
|
||||
if( pagerUseWal(pPager) ){
|
||||
/* Try to pull the page from the write-ahead log. */
|
||||
rc = sqlite3WalRead(pPager->pWal, pgno, &isInWal, pgsz, pPg->pData);
|
||||
}
|
||||
if( rc==SQLITE_OK && !isInWal ){
|
||||
i64 iOffset = (pgno-1)*(i64)pPager->pageSize;
|
||||
rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset);
|
||||
if( rc==SQLITE_IOERR_SHORT_READ ){
|
||||
rc = SQLITE_OK;
|
||||
i64 iOffset = (pgno-1)*(i64)pgsz;
|
||||
if( iOffset+pgsz <= pPager->nFileContent ){
|
||||
pPg->pData = &pPager->aFileContent[iOffset];
|
||||
}else{
|
||||
rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset);
|
||||
if( rc==SQLITE_IOERR_SHORT_READ ){
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4892,6 +4909,13 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
||||
rc = pagerPagecount(pPager, &pPager->dbSize);
|
||||
}
|
||||
|
||||
assert( pPager->aFileContent==0 );
|
||||
pPager->nFileContent = pPager->dbSize*(sqlite3_int64)pPager->pageSize;
|
||||
sqlite3OsMap(pPager->fd, 0, pPager->nFileContent,
|
||||
SQLITE_OPEN_READONLY, (void**)&pPager->pMapObject,
|
||||
(void**)&pPager->aFileContent);
|
||||
if( pPager->aFileContent==0 ) pPager->nFileContent = 0;
|
||||
|
||||
failed:
|
||||
if( rc!=SQLITE_OK ){
|
||||
assert( !MEMDB );
|
||||
@@ -5277,6 +5301,16 @@ int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Make a copy of page content into malloced space.
|
||||
*/
|
||||
void makePageWriteable(Pager *pPager, PgHdr *pPg){
|
||||
if( pPg->pData!=pPg->pBuf ){
|
||||
memcpy(pPg->pBuf, pPg->pData, pPager->pageSize);
|
||||
pPg->pData = pPg->pBuf;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Mark a single data page as writeable. The page is written into the
|
||||
** main journal or sub-journal as required. If the page is written into
|
||||
@@ -5325,6 +5359,10 @@ static int pager_write(PgHdr *pPg){
|
||||
assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
|
||||
assert( assert_pager_state(pPager) );
|
||||
|
||||
/* Make sure page content is held in malloced memory */
|
||||
makePageWriteable(pPager, pPg);
|
||||
pData = pPg->pData;
|
||||
|
||||
/* Mark the page as dirty. If the page has already been written
|
||||
** to the journal then we can return right away.
|
||||
*/
|
||||
@@ -5525,11 +5563,9 @@ int sqlite3PagerWrite(DbPage *pDbPage){
|
||||
** to sqlite3PagerWrite(). In other words, return TRUE if it is ok
|
||||
** to change the content of the page.
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
int sqlite3PagerIswriteable(DbPage *pPg){
|
||||
return pPg->flags&PGHDR_DIRTY;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** A call to this routine tells the pager that it is not necessary to
|
||||
@@ -6419,6 +6455,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
|
||||
}
|
||||
|
||||
origPgno = pPg->pgno;
|
||||
makePageWriteable(pPager, pPg);
|
||||
sqlite3PcacheMove(pPg, pgno);
|
||||
sqlite3PcacheMakeDirty(pPg);
|
||||
|
||||
@@ -6468,9 +6505,9 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
|
||||
/*
|
||||
** Return a pointer to the data for the specified page.
|
||||
*/
|
||||
void *sqlite3PagerGetData(DbPage *pPg){
|
||||
u8 *sqlite3PagerGetData(DbPage *pPg){
|
||||
assert( pPg->nRef>0 || pPg->pPager->memDb );
|
||||
return pPg->pData;
|
||||
return (u8*)pPg->pData;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+2
-2
@@ -123,7 +123,7 @@ int sqlite3PagerWrite(DbPage*);
|
||||
void sqlite3PagerDontWrite(DbPage*);
|
||||
int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int);
|
||||
int sqlite3PagerPageRefcount(DbPage*);
|
||||
void *sqlite3PagerGetData(DbPage *);
|
||||
u8 *sqlite3PagerGetData(DbPage *);
|
||||
void *sqlite3PagerGetExtra(DbPage *);
|
||||
|
||||
/* Functions used to manage pager transactions and savepoints. */
|
||||
@@ -168,8 +168,8 @@ void *sqlite3PagerCodec(DbPage *);
|
||||
/* Functions to support testing and debugging. */
|
||||
#if !defined(NDEBUG) || defined(SQLITE_TEST)
|
||||
Pgno sqlite3PagerPagenumber(DbPage*);
|
||||
int sqlite3PagerIswriteable(DbPage*);
|
||||
#endif
|
||||
int sqlite3PagerIswriteable(DbPage*);
|
||||
#ifdef SQLITE_TEST
|
||||
int *sqlite3PagerStats(Pager*);
|
||||
void sqlite3PagerRefdump(Pager*);
|
||||
|
||||
+3
-3
@@ -131,7 +131,7 @@ static void pcacheUnpin(PgHdr *p){
|
||||
if( p->pgno==1 ){
|
||||
pCache->pPage1 = 0;
|
||||
}
|
||||
sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 0);
|
||||
sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,7 +287,7 @@ int sqlite3PcacheFetch(
|
||||
if( !pPgHdr->pPage ){
|
||||
memset(pPgHdr, 0, sizeof(PgHdr));
|
||||
pPgHdr->pPage = pPage;
|
||||
pPgHdr->pData = pPage->pBuf;
|
||||
pPgHdr->pData = pPgHdr->pBuf = pPage->pBuf;
|
||||
pPgHdr->pExtra = (void *)&pPgHdr[1];
|
||||
memset(pPgHdr->pExtra, 0, pCache->szExtra);
|
||||
pPgHdr->pCache = pCache;
|
||||
@@ -295,7 +295,7 @@ int sqlite3PcacheFetch(
|
||||
}
|
||||
assert( pPgHdr->pCache==pCache );
|
||||
assert( pPgHdr->pgno==pgno );
|
||||
assert( pPgHdr->pData==pPage->pBuf );
|
||||
assert( pPgHdr->pBuf==pPage->pBuf );
|
||||
assert( pPgHdr->pExtra==(void *)&pPgHdr[1] );
|
||||
|
||||
if( 0==pPgHdr->nRef ){
|
||||
|
||||
+2
-1
@@ -24,7 +24,8 @@ typedef struct PCache PCache;
|
||||
*/
|
||||
struct PgHdr {
|
||||
sqlite3_pcache_page *pPage; /* Pcache object page handle */
|
||||
void *pData; /* Page data */
|
||||
void *pData; /* Page data to actually use */
|
||||
void *pBuf; /* Malloced buffer to hold pData */
|
||||
void *pExtra; /* Extra content */
|
||||
PgHdr *pDirty; /* Transient list of dirty pages */
|
||||
Pgno pgno; /* Page number for this page */
|
||||
|
||||
@@ -689,6 +689,10 @@ struct sqlite3_io_methods {
|
||||
void (*xShmBarrier)(sqlite3_file*);
|
||||
int (*xShmUnmap)(sqlite3_file*, int deleteFlag);
|
||||
/* Methods above are valid for version 2 */
|
||||
int (*xMap)(sqlite3_file*, sqlite3_int64 ofst, sqlite3_int64 len,
|
||||
int mmapFlags, void **ppMemObj, void **ppMem);
|
||||
int (*xUnmap)(sqlite3_file*, void *pMemObj);
|
||||
/* Methods above are valid for version 3 */
|
||||
/* Additional methods may be added in future releases */
|
||||
};
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ foreach s {
|
||||
open close access getcwd stat fstat ftruncate
|
||||
fcntl read pread write pwrite fchmod fallocate
|
||||
pread64 pwrite64 unlink openDirectory mkdir rmdir
|
||||
mmap munmap
|
||||
} {
|
||||
if {[test_syscall exists $s]} {lappend syscall_list $s}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user