Compare commits

...

2 Commits

Author SHA1 Message Date
drh b6ae41ab93 Further work on mmap(). Still does not work right - autovacuum tests are the
first to fail.

FossilOrigin-Name: 638a39bbaa034a08d73459a36bbe14b76b34189f
2011-11-14 12:34:15 +00:00
drh 387dd1bffc Begin making experimental changes to use mmap() for reading content from
a database.  The code compiles, but crashes on the test suite.

FossilOrigin-Name: 09be42d5fa7ef692428579d4d8d48b3316190945
2011-11-14 01:55:02 +00:00
12 changed files with 289 additions and 106 deletions
+15 -15
View File
@@ -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
View File
@@ -1 +1 @@
9f839ac05a9f3cfe587d2ccdccd50dac41baedbe
638a39bbaa034a08d73459a36bbe14b76b34189f
+74 -47
View File
@@ -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;
}
+46
View File
@@ -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,
+2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
+4
View File
@@ -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 */
};
+1
View File
@@ -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}
}