Getting ready to redo the journal file format. (CVS 210)

FossilOrigin-Name: 42c2f3fe68c8a6bab96e035371ecd64296c5491f
This commit is contained in:
drh 2001-04-14 16:38:23 +00:00
parent d400728ac1
commit 69688d5f54
3 changed files with 53 additions and 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

@ -1 +1 @@
3bde128418fe70a2fd62bf9e013999827a16053c
42c2f3fe68c8a6bab96e035371ecd64296c5491f

@ -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);