diff options
-rw-r--r-- | manifest | 12 | ||||
-rw-r--r-- | manifest.uuid | 2 | ||||
-rw-r--r-- | src/pager.c | 54 |
3 files changed, 53 insertions, 15 deletions
@@ -1,5 +1,5 @@ -C More\stesting\s(CVS\s209) -D 2001-04-12T23:21:59 +C Getting\sready\sto\sredo\sthe\sjournal\sfile\sformat.\s(CVS\s210) +D 2001-04-14T16:38:23 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4 F Makefile.in 4775f7fd1ed543606bb24fa3fada1bc90a23a6b9 F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958 @@ -26,7 +26,7 @@ F src/ex/sizes.tcl f54bad4a2ac567624be59131a6ee42d71b41a3d7 F src/expr.c c4c24c3af1eba094a816522eb0e085bed518ee16 F src/insert.c aa528e20a787af85432a61daaea6df394bd251d7 F src/main.c 92ce30a89f622ba36cc8b7d912829e14a480722c -F src/pager.c 0aa36ee4038369fb7537871950d192e5e93d5530 +F src/pager.c 67227909b9a16a2463bbfddf19347fcab7a251ae F src/pager.h 889c5cf517ad30704e295540793c893ac843fd5f F src/parse.y 8fc096948994a7ffbf61ba13129cc589f794a9cb F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9 @@ -99,7 +99,7 @@ F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2 F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad -P 555351dd1918f96167e2cb46cc1db6496e8d10a3 -R 88f43cdb122b3ed28d135a7a6386c93b +P 3bde128418fe70a2fd62bf9e013999827a16053c +R e5aeeb4c78022c778bcfebd97e61f590 U drh -Z f62bd098004466e47e342be3c2445c9d +Z 3ef685e141624dcddb66699cb8550c69 diff --git a/manifest.uuid b/manifest.uuid index 048449f22..f175fd505 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3bde128418fe70a2fd62bf9e013999827a16053c
\ No newline at end of file +42c2f3fe68c8a6bab96e035371ecd64296c5491f
\ No newline at end of file diff --git a/src/pager.c b/src/pager.c index a763d7d89..41650d98f 100644 --- a/src/pager.c +++ b/src/pager.c @@ -27,7 +27,7 @@ ** all writes in order to support rollback. Locking is used to limit ** access to one or more reader or on writer. ** -** @(#) $Id: pager.c,v 1.1 2001/04/11 14:29:22 drh Exp $ +** @(#) $Id: pager.c,v 1.2 2001/04/14 16:38:23 drh Exp $ */ #include "pager.h" #include <fcntl.h> @@ -47,7 +47,7 @@ ** SQLITE_READLOCK The page cache is reading the database. ** Writing is not permitted. There can be ** multiple readers accessing the same database -** at the same time. +** file at the same time. ** ** SQLITE_WRITELOCK The page cache is writing the database. ** Access is exclusive. No other processes or @@ -72,17 +72,17 @@ struct PgHdr { Pager *pPager; /* The pager to which this page belongs */ Pgno pgno; /* The page number for this page */ - PgHdr *pNextHash, *pPrevHash; /* Hash collision change for PgHdr.pgno */ + PgHdr *pNextHash, *pPrevHash; /* Hash collision chain for PgHdr.pgno */ int nRef; /* Number of users of this page */ PgHdr *pNext, *pPrev; /* Freelist of pages where nRef==0 */ char inJournal; /* TRUE if has been written to journal */ char dirty; /* TRUE if we need to write back changes */ - /* The page data follows this header */ + /* SQLITE_PAGE_SIZE bytes of page data follow this header */ }; /* -** Convert a pointer to a PgHdr into a pointer to its data, -** and vice verse. +** Convert a pointer to a PgHdr into a pointer to its data +** and back again. */ #define PGHDR_TO_DATA(P) ((void*)(&(P)[1])) #define DATA_TO_PGHDR(D) (&((PgHdr*)(D))[-1]) @@ -107,13 +107,16 @@ struct Pager { int fd, jfd; /* File descriptors for database and journal */ int nRef; /* Sum of PgHdr.nRef */ int dbSize; /* Number of pages in the file */ + int origDbSize; /* dbSize before the current change */ int jSize; /* Number of pages in the journal */ + int nIdx; /* Number of entries in aIdx[] */ int nPage; /* Total number of in-memory pages */ int mxPage; /* Maximum number of pages to hold in cache */ - Pgno *aIdx; /* Current journal index page */ char state; /* SQLITE_UNLOCK, _READLOCK or _WRITELOCK */ + char ioErr; /* True if an I/O error has occurred */ PgHdr *pFirst, *pLast; /* List of free pages */ PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number of PgHdr */ + Pgno aIdx[SQLITE_INDEX_SIZE]; /* Current journal index page */ }; /* @@ -610,6 +613,12 @@ int sqlite_pager_unref(void *pData){ ** change any page data until this routine returns SQLITE_OK. */ int sqlite_pager_write(void *pData){ + PgHdr *pPg = DATA_TO_PGHDR(pData); + Pager *pPager = pPg->pPager; + int rc; + + if( pPg->inJournal ){ return SQLITE_OK; } + if( pPager->state==SQLITE_UNLOCK ){ return SQLITE_PROTOCOL; } if( pPager->state==SQLITE_READLOCK ){ pPager->jfd = open(pPager->zJournal, O_RDWR|O_CREAT, 0644); if( pPager->jfd<0 ){ @@ -629,9 +638,30 @@ int sqlite_pager_write(void *pData){ return SQLITE_PROTOCOL; } pPager->state = SQLITE_WRITELOCK; - pPager->jSize = 0; + pPager->jSize = 1; + pPager->aIdx[0] = pPager->dbSize; + pPager->origDbSize = pPager->dbSize; + pPager->nIdx = 1; } /* Write this page to the journal */ + assert( pPager->jfd>=0 ); + if( pPg->pgno >= pPager->origDbSize ){ + sqlite_pager_seekpage(pPager->fd, pPg->pgno, SEEK_SET); + rc = sqlite_pager_writepage(pPager->fd, pData); + pPg->inJournal = 1; + return rc; + } + pPager->aIdx[pPager->nIdx++] = pPg->pgno; + sqlite_pager_seekpage(pPager->jfd, pPager->jSize++, SEEK_SET); + rc = sqlite_pager_write(pPager->jfd, pData); + pPg->inJournal = 1; + if( pPager->nIdx==SQLITE_INDEX_SIZE ){ + sqlite_pager_seekpage(pPager->jfd, pPager->idxPgno, SEEK_SET); + rc = sqlite_pager_writepage(pPager->jfd, &pPager->aIdx); + pPager->nIdx = 0; + pPager->jSize++; + } + return rc; } /* @@ -642,6 +672,10 @@ int sqlite_pager_commit(Pager*){ PgHdr *pPg; assert( pPager->state==SQLITE_WRITELOCK ); assert( pPager->jfd>=0 ); + memset(&pPager->aIdx[&pPager->nIdx], 0, + (SQLITE_INDEX_SIZE - pPager->nIdx)*sizeof(Pgno)); + sqlite_pager_seekpage(pPager->jfd, pPager->idxPgno, SEEK_SET); + rc = sqlite_pager_writepage(pPager->jfd, &pPager->aIdx); if( fsync(pPager->jfd) ){ return SQLITE_IOERR; } @@ -669,6 +703,10 @@ int sqlite_pager_commit(Pager*){ int sqlite_pager_rollback(Pager *pPager){ int rc; if( pPager->state!=SQLITE_WRITELOCK ) return SQLITE_OK; + memset(&pPager->aIdx[&pPager->nIdx], 0, + (SQLITE_INDEX_SIZE - pPager->nIdx)*sizeof(Pgno)); + sqlite_pager_seekpage(pPager->jfd, pPager->idxPgno, SEEK_SET); + rc = sqlite_pager_writepage(pPager->jfd, &pPager->aIdx); rc = sqlite_pager_playback(pPager); if( rc!=SQLITE_OK ){ rc = sqlite_pager_unwritelock(pPager); |