blob: a6f112a5c8f9179fb00d97b9d98e8bd293a1b2d0 [file] [log] [blame]
drhed7c8552001-04-11 14:29:21 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drhed7c8552001-04-11 14:29:21 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drhed7c8552001-04-11 14:29:21 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drhed7c8552001-04-11 14:29:21 +000010**
11*************************************************************************
drhb19a2bc2001-09-16 00:13:26 +000012** This is the implementation of the page cache subsystem or "pager".
drhed7c8552001-04-11 14:29:21 +000013**
drhb19a2bc2001-09-16 00:13:26 +000014** The pager is used to access a database disk file. It implements
15** atomic commit and rollback through the use of a journal file that
16** is separate from the database file. The pager also implements file
17** locking to prevent two processes from writing the same database
18** file simultaneously, or one process from reading the database while
19** another is writing.
drhed7c8552001-04-11 14:29:21 +000020**
drhfa86c412002-02-02 15:01:15 +000021** @(#) $Id: pager.c,v 1.37 2002/02/02 15:01:16 drh Exp $
drhed7c8552001-04-11 14:29:21 +000022*/
drhd9b02572001-04-15 00:37:09 +000023#include "sqliteInt.h"
drhed7c8552001-04-11 14:29:21 +000024#include "pager.h"
drh8cfbf082001-09-19 13:22:39 +000025#include "os.h"
drhed7c8552001-04-11 14:29:21 +000026#include <assert.h>
drhd9b02572001-04-15 00:37:09 +000027#include <string.h>
drhed7c8552001-04-11 14:29:21 +000028
29/*
30** The page cache as a whole is always in one of the following
31** states:
32**
33** SQLITE_UNLOCK The page cache is not currently reading or
34** writing the database file. There is no
35** data held in memory. This is the initial
36** state.
37**
38** SQLITE_READLOCK The page cache is reading the database.
39** Writing is not permitted. There can be
40** multiple readers accessing the same database
drh69688d52001-04-14 16:38:23 +000041** file at the same time.
drhed7c8552001-04-11 14:29:21 +000042**
43** SQLITE_WRITELOCK The page cache is writing the database.
44** Access is exclusive. No other processes or
45** threads can be reading or writing while one
46** process is writing.
47**
drhfa86c412002-02-02 15:01:15 +000048** SQLITE_CHECKPOINT The page cache is writing to the database and
49** preserving its changes so that it can back them
50** out later if need be.
51**
drh306dc212001-05-21 13:45:10 +000052** The page cache comes up in SQLITE_UNLOCK. The first time a
53** sqlite_page_get() occurs, the state transitions to SQLITE_READLOCK.
drhed7c8552001-04-11 14:29:21 +000054** After all pages have been released using sqlite_page_unref(),
drh306dc212001-05-21 13:45:10 +000055** the state transitions back to SQLITE_UNLOCK. The first time
drhed7c8552001-04-11 14:29:21 +000056** that sqlite_page_write() is called, the state transitions to
drh306dc212001-05-21 13:45:10 +000057** SQLITE_WRITELOCK. (Note that sqlite_page_write() can only be
58** called on an outstanding page which means that the pager must
59** be in SQLITE_READLOCK before it transitions to SQLITE_WRITELOCK.)
60** The sqlite_page_rollback() and sqlite_page_commit() functions
61** transition the state from SQLITE_WRITELOCK back to SQLITE_READLOCK.
drhfa86c412002-02-02 15:01:15 +000062**
63** The sqlite_ckpt_begin() function moves the state from SQLITE_WRITELOCK
64** to SQLITE_CHECKPOINT. The state transitions back to SQLITE_WRITELOCK
65** on calls to sqlite_ckpt_commit() or sqlite_ckpt_rollback(). While
66** in SQLITE_CHECKPOINT, calls to sqlite_commit() or sqlite_rollback()
67** transition directly back to SQLITE_READLOCK.
68**
69** The code does unequality comparisons on these constants so the order
70** must be preserved.
drhed7c8552001-04-11 14:29:21 +000071*/
72#define SQLITE_UNLOCK 0
73#define SQLITE_READLOCK 1
74#define SQLITE_WRITELOCK 2
drhfa86c412002-02-02 15:01:15 +000075#define SQLITE_CHECKPOINT 3
drhed7c8552001-04-11 14:29:21 +000076
drhd9b02572001-04-15 00:37:09 +000077
drhed7c8552001-04-11 14:29:21 +000078/*
79** Each in-memory image of a page begins with the following header.
drhbd03cae2001-06-02 02:40:57 +000080** This header is only visible to this pager module. The client
81** code that calls pager sees only the data that follows the header.
drhed7c8552001-04-11 14:29:21 +000082*/
drhd9b02572001-04-15 00:37:09 +000083typedef struct PgHdr PgHdr;
drhed7c8552001-04-11 14:29:21 +000084struct PgHdr {
85 Pager *pPager; /* The pager to which this page belongs */
86 Pgno pgno; /* The page number for this page */
drh69688d52001-04-14 16:38:23 +000087 PgHdr *pNextHash, *pPrevHash; /* Hash collision chain for PgHdr.pgno */
drhed7c8552001-04-11 14:29:21 +000088 int nRef; /* Number of users of this page */
drhd9b02572001-04-15 00:37:09 +000089 PgHdr *pNextFree, *pPrevFree; /* Freelist of pages where nRef==0 */
90 PgHdr *pNextAll, *pPrevAll; /* A list of all pages */
drhed7c8552001-04-11 14:29:21 +000091 char inJournal; /* TRUE if has been written to journal */
drhfa86c412002-02-02 15:01:15 +000092 char inCkpt; /* TRUE if written to the checkpoint journal */
drhed7c8552001-04-11 14:29:21 +000093 char dirty; /* TRUE if we need to write back changes */
drh69688d52001-04-14 16:38:23 +000094 /* SQLITE_PAGE_SIZE bytes of page data follow this header */
drh7e3b0a02001-04-28 16:52:40 +000095 /* Pager.nExtra bytes of local data follow the page data */
drhed7c8552001-04-11 14:29:21 +000096};
97
98/*
drh69688d52001-04-14 16:38:23 +000099** Convert a pointer to a PgHdr into a pointer to its data
100** and back again.
drhed7c8552001-04-11 14:29:21 +0000101*/
102#define PGHDR_TO_DATA(P) ((void*)(&(P)[1]))
103#define DATA_TO_PGHDR(D) (&((PgHdr*)(D))[-1])
drh7e3b0a02001-04-28 16:52:40 +0000104#define PGHDR_TO_EXTRA(P) ((void*)&((char*)(&(P)[1]))[SQLITE_PAGE_SIZE])
drhed7c8552001-04-11 14:29:21 +0000105
106/*
drhed7c8552001-04-11 14:29:21 +0000107** How big to make the hash table used for locating in-memory pages
drh306dc212001-05-21 13:45:10 +0000108** by page number. Knuth says this should be a prime number.
drhed7c8552001-04-11 14:29:21 +0000109*/
drhb19a2bc2001-09-16 00:13:26 +0000110#define N_PG_HASH 373
drhed7c8552001-04-11 14:29:21 +0000111
112/*
113** A open page cache is an instance of the following structure.
114*/
115struct Pager {
116 char *zFilename; /* Name of the database file */
117 char *zJournal; /* Name of the journal file */
drh8cfbf082001-09-19 13:22:39 +0000118 OsFile fd, jfd; /* File descriptors for database and journal */
drhfa86c412002-02-02 15:01:15 +0000119 OsFile cpfd; /* File descriptor for the checkpoint journal */
drh8cfbf082001-09-19 13:22:39 +0000120 int journalOpen; /* True if journal file descriptors is valid */
drhfa86c412002-02-02 15:01:15 +0000121 int ckptOpen; /* True if the checkpoint journal is open */
drhed7c8552001-04-11 14:29:21 +0000122 int dbSize; /* Number of pages in the file */
drh69688d52001-04-14 16:38:23 +0000123 int origDbSize; /* dbSize before the current change */
drhfa86c412002-02-02 15:01:15 +0000124 int ckptSize, ckptJSize; /* Size of database and journal at ckpt_begin() */
drh7e3b0a02001-04-28 16:52:40 +0000125 int nExtra; /* Add this many bytes to each in-memory page */
drh72f82862001-05-24 21:06:34 +0000126 void (*xDestructor)(void*); /* Call this routine when freeing pages */
drhed7c8552001-04-11 14:29:21 +0000127 int nPage; /* Total number of in-memory pages */
drhd9b02572001-04-15 00:37:09 +0000128 int nRef; /* Number of in-memory pages with PgHdr.nRef>0 */
drhed7c8552001-04-11 14:29:21 +0000129 int mxPage; /* Maximum number of pages to hold in cache */
drhd9b02572001-04-15 00:37:09 +0000130 int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */
131 unsigned char state; /* SQLITE_UNLOCK, _READLOCK or _WRITELOCK */
132 unsigned char errMask; /* One of several kinds of errors */
drh5e00f6c2001-09-13 13:46:56 +0000133 unsigned char tempFile; /* zFilename is a temporary file */
134 unsigned char readOnly; /* True for a read-only database */
drhf57b14a2001-09-14 18:54:08 +0000135 unsigned char needSync; /* True if an fsync() is needed on the journal */
drh6019e162001-07-02 17:51:45 +0000136 unsigned char *aInJournal; /* One bit for each page in the database file */
drhfa86c412002-02-02 15:01:15 +0000137 unsigned char *aInCkpt; /* One bit for each page in the database */
drhed7c8552001-04-11 14:29:21 +0000138 PgHdr *pFirst, *pLast; /* List of free pages */
drhd9b02572001-04-15 00:37:09 +0000139 PgHdr *pAll; /* List of all pages */
drhed7c8552001-04-11 14:29:21 +0000140 PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number of PgHdr */
drhd9b02572001-04-15 00:37:09 +0000141};
142
143/*
144** These are bits that can be set in Pager.errMask.
145*/
146#define PAGER_ERR_FULL 0x01 /* a write() failed */
147#define PAGER_ERR_MEM 0x02 /* malloc() failed */
148#define PAGER_ERR_LOCK 0x04 /* error in the locking protocol */
149#define PAGER_ERR_CORRUPT 0x08 /* database or journal corruption */
drh81a20f22001-10-12 17:30:04 +0000150#define PAGER_ERR_DISK 0x10 /* general disk I/O error - bad hard drive? */
drhd9b02572001-04-15 00:37:09 +0000151
152/*
153** The journal file contains page records in the following
154** format.
155*/
156typedef struct PageRecord PageRecord;
157struct PageRecord {
158 Pgno pgno; /* The page number */
159 char aData[SQLITE_PAGE_SIZE]; /* Original data for page pgno */
160};
161
162/*
drh5e00f6c2001-09-13 13:46:56 +0000163** Journal files begin with the following magic string. The data
164** was obtained from /dev/random. It is used only as a sanity check.
drhd9b02572001-04-15 00:37:09 +0000165*/
166static const unsigned char aJournalMagic[] = {
167 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd4,
drhed7c8552001-04-11 14:29:21 +0000168};
169
170/*
171** Hash a page number
172*/
drhd9b02572001-04-15 00:37:09 +0000173#define pager_hash(PN) ((PN)%N_PG_HASH)
drhed7c8552001-04-11 14:29:21 +0000174
175/*
drhdd793422001-06-28 01:54:48 +0000176** Enable reference count tracking here:
177*/
178#if SQLITE_TEST
drh5e00f6c2001-09-13 13:46:56 +0000179 int pager_refinfo_enable = 0;
drhdd793422001-06-28 01:54:48 +0000180 static void pager_refinfo(PgHdr *p){
181 static int cnt = 0;
182 if( !pager_refinfo_enable ) return;
183 printf(
184 "REFCNT: %4d addr=0x%08x nRef=%d\n",
185 p->pgno, (int)PGHDR_TO_DATA(p), p->nRef
186 );
187 cnt++; /* Something to set a breakpoint on */
188 }
189# define REFINFO(X) pager_refinfo(X)
190#else
191# define REFINFO(X)
192#endif
193
194/*
drhd9b02572001-04-15 00:37:09 +0000195** Convert the bits in the pPager->errMask into an approprate
196** return code.
197*/
198static int pager_errcode(Pager *pPager){
199 int rc = SQLITE_OK;
200 if( pPager->errMask & PAGER_ERR_LOCK ) rc = SQLITE_PROTOCOL;
drh81a20f22001-10-12 17:30:04 +0000201 if( pPager->errMask & PAGER_ERR_DISK ) rc = SQLITE_IOERR;
drhd9b02572001-04-15 00:37:09 +0000202 if( pPager->errMask & PAGER_ERR_FULL ) rc = SQLITE_FULL;
203 if( pPager->errMask & PAGER_ERR_MEM ) rc = SQLITE_NOMEM;
204 if( pPager->errMask & PAGER_ERR_CORRUPT ) rc = SQLITE_CORRUPT;
205 return rc;
drhed7c8552001-04-11 14:29:21 +0000206}
207
208/*
209** Find a page in the hash table given its page number. Return
210** a pointer to the page or NULL if not found.
211*/
drhd9b02572001-04-15 00:37:09 +0000212static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
drhed7c8552001-04-11 14:29:21 +0000213 PgHdr *p = pPager->aHash[pgno % N_PG_HASH];
214 while( p && p->pgno!=pgno ){
215 p = p->pNextHash;
216 }
217 return p;
218}
219
220/*
221** Unlock the database and clear the in-memory cache. This routine
222** sets the state of the pager back to what it was when it was first
223** opened. Any outstanding pages are invalidated and subsequent attempts
224** to access those pages will likely result in a coredump.
225*/
drhd9b02572001-04-15 00:37:09 +0000226static void pager_reset(Pager *pPager){
drhed7c8552001-04-11 14:29:21 +0000227 PgHdr *pPg, *pNext;
drhd9b02572001-04-15 00:37:09 +0000228 for(pPg=pPager->pAll; pPg; pPg=pNext){
229 pNext = pPg->pNextAll;
230 sqliteFree(pPg);
drhed7c8552001-04-11 14:29:21 +0000231 }
232 pPager->pFirst = 0;
drhd9b02572001-04-15 00:37:09 +0000233 pPager->pLast = 0;
234 pPager->pAll = 0;
drhed7c8552001-04-11 14:29:21 +0000235 memset(pPager->aHash, 0, sizeof(pPager->aHash));
236 pPager->nPage = 0;
drhfa86c412002-02-02 15:01:15 +0000237 if( pPager->state>=SQLITE_WRITELOCK ){
drhd9b02572001-04-15 00:37:09 +0000238 sqlitepager_rollback(pPager);
drhed7c8552001-04-11 14:29:21 +0000239 }
drha7fcb052001-12-14 15:09:55 +0000240 sqliteOsUnlock(&pPager->fd);
drhed7c8552001-04-11 14:29:21 +0000241 pPager->state = SQLITE_UNLOCK;
drhd9b02572001-04-15 00:37:09 +0000242 pPager->dbSize = -1;
drhed7c8552001-04-11 14:29:21 +0000243 pPager->nRef = 0;
drh8cfbf082001-09-19 13:22:39 +0000244 assert( pPager->journalOpen==0 );
drhed7c8552001-04-11 14:29:21 +0000245}
246
247/*
248** When this routine is called, the pager has the journal file open and
249** a write lock on the database. This routine releases the database
250** write lock and acquires a read lock in its place. The journal file
251** is deleted and closed.
drhed7c8552001-04-11 14:29:21 +0000252*/
drhd9b02572001-04-15 00:37:09 +0000253static int pager_unwritelock(Pager *pPager){
drhed7c8552001-04-11 14:29:21 +0000254 int rc;
drhd9b02572001-04-15 00:37:09 +0000255 PgHdr *pPg;
drhfa86c412002-02-02 15:01:15 +0000256 if( pPager->state<SQLITE_WRITELOCK ) return SQLITE_OK;
drha7fcb052001-12-14 15:09:55 +0000257 sqliteOsClose(&pPager->jfd);
drh8cfbf082001-09-19 13:22:39 +0000258 pPager->journalOpen = 0;
259 sqliteOsDelete(pPager->zJournal);
drha7fcb052001-12-14 15:09:55 +0000260 rc = sqliteOsReadLock(&pPager->fd);
261 assert( rc==SQLITE_OK );
drhfa86c412002-02-02 15:01:15 +0000262 sqliteFree( pPager->aInCkpt );
drh6019e162001-07-02 17:51:45 +0000263 sqliteFree( pPager->aInJournal );
264 pPager->aInJournal = 0;
drhd9b02572001-04-15 00:37:09 +0000265 for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
266 pPg->inJournal = 0;
267 pPg->dirty = 0;
268 }
drha7fcb052001-12-14 15:09:55 +0000269 pPager->state = SQLITE_READLOCK;
drhed7c8552001-04-11 14:29:21 +0000270 return rc;
271}
272
drhed7c8552001-04-11 14:29:21 +0000273/*
drhfa86c412002-02-02 15:01:15 +0000274** Read a single page from the journal file opened on file descriptor
275** jfd. Playback this one page.
276*/
277static int pager_playback_one_page(Pager *pPager, OsFile *jfd){
278 int rc;
279 PgHdr *pPg; /* An existing page in the cache */
280 PageRecord pgRec;
281
282 rc = sqliteOsRead(&pPager->jfd, &pgRec, sizeof(pgRec));
283 if( rc!=SQLITE_OK ) return rc;
284
285 /* Sanity checking on the page */
286 if( pgRec.pgno>pPager->dbSize || pgRec.pgno==0 ) return SQLITE_CORRUPT;
287
288 /* Playback the page. Update the in-memory copy of the page
289 ** at the same time, if there is one.
290 */
291 pPg = pager_lookup(pPager, pgRec.pgno);
292 if( pPg ){
293 memcpy(PGHDR_TO_DATA(pPg), pgRec.aData, SQLITE_PAGE_SIZE);
294 memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
295 }
296 rc = sqliteOsSeek(&pPager->fd, (pgRec.pgno-1)*SQLITE_PAGE_SIZE);
297 if( rc==SQLITE_OK ){
298 rc = sqliteOsWrite(&pPager->fd, pgRec.aData, SQLITE_PAGE_SIZE);
299 }
300 return rc;
301}
302
303/*
drhed7c8552001-04-11 14:29:21 +0000304** Playback the journal and thus restore the database file to
305** the state it was in before we started making changes.
306**
drhd9b02572001-04-15 00:37:09 +0000307** The journal file format is as follows: There is an initial
308** file-type string for sanity checking. Then there is a single
309** Pgno number which is the number of pages in the database before
310** changes were made. The database is truncated to this size.
drh306dc212001-05-21 13:45:10 +0000311** Next come zero or more page records where each page record
312** consists of a Pgno and SQLITE_PAGE_SIZE bytes of data. See
313** the PageRecord structure for details.
drhed7c8552001-04-11 14:29:21 +0000314**
drhd9b02572001-04-15 00:37:09 +0000315** If the file opened as the journal file is not a well-formed
316** journal file (as determined by looking at the magic number
317** at the beginning) then this routine returns SQLITE_PROTOCOL.
318** If any other errors occur during playback, the database will
319** likely be corrupted, so the PAGER_ERR_CORRUPT bit is set in
320** pPager->errMask and SQLITE_CORRUPT is returned. If it all
321** works, then this routine returns SQLITE_OK.
drhed7c8552001-04-11 14:29:21 +0000322*/
drhd9b02572001-04-15 00:37:09 +0000323static int pager_playback(Pager *pPager){
324 int nRec; /* Number of Records */
325 int i; /* Loop counter */
326 Pgno mxPg = 0; /* Size of the original file in pages */
drhd9b02572001-04-15 00:37:09 +0000327 unsigned char aMagic[sizeof(aJournalMagic)];
drhed7c8552001-04-11 14:29:21 +0000328 int rc;
329
drhc3a64ba2001-11-22 00:01:27 +0000330 /* Figure out how many records are in the journal. Abort early if
331 ** the journal is empty.
drhed7c8552001-04-11 14:29:21 +0000332 */
drh8cfbf082001-09-19 13:22:39 +0000333 assert( pPager->journalOpen );
drha7fcb052001-12-14 15:09:55 +0000334 sqliteOsSeek(&pPager->jfd, 0);
335 rc = sqliteOsFileSize(&pPager->jfd, &nRec);
drhc3a64ba2001-11-22 00:01:27 +0000336 if( rc!=SQLITE_OK ){
337 goto end_playback;
338 }
339 nRec = (nRec - (sizeof(aMagic)+sizeof(Pgno))) / sizeof(PageRecord);
340 if( nRec<=0 ){
341 goto end_playback;
342 }
343
344 /* Read the beginning of the journal and truncate the
345 ** database file back to its original size.
346 */
drha7fcb052001-12-14 15:09:55 +0000347 rc = sqliteOsRead(&pPager->jfd, aMagic, sizeof(aMagic));
drhd9b02572001-04-15 00:37:09 +0000348 if( rc!=SQLITE_OK || memcmp(aMagic,aJournalMagic,sizeof(aMagic))!=0 ){
drh81a20f22001-10-12 17:30:04 +0000349 rc = SQLITE_PROTOCOL;
350 goto end_playback;
drhd9b02572001-04-15 00:37:09 +0000351 }
drha7fcb052001-12-14 15:09:55 +0000352 rc = sqliteOsRead(&pPager->jfd, &mxPg, sizeof(mxPg));
drhd9b02572001-04-15 00:37:09 +0000353 if( rc!=SQLITE_OK ){
drh81a20f22001-10-12 17:30:04 +0000354 goto end_playback;
drhd9b02572001-04-15 00:37:09 +0000355 }
drha7fcb052001-12-14 15:09:55 +0000356 rc = sqliteOsTruncate(&pPager->fd, mxPg*SQLITE_PAGE_SIZE);
drh81a20f22001-10-12 17:30:04 +0000357 if( rc!=SQLITE_OK ){
358 goto end_playback;
359 }
drhd9b02572001-04-15 00:37:09 +0000360 pPager->dbSize = mxPg;
361
drhfa86c412002-02-02 15:01:15 +0000362 /* Copy original pages out of the journal and back into the database file.
drhed7c8552001-04-11 14:29:21 +0000363 */
drhd9b02572001-04-15 00:37:09 +0000364 for(i=nRec-1; i>=0; i--){
drhfa86c412002-02-02 15:01:15 +0000365 rc = pager_playback_one_page(pPager, &pPager->jfd);
drhd9b02572001-04-15 00:37:09 +0000366 if( rc!=SQLITE_OK ) break;
drhed7c8552001-04-11 14:29:21 +0000367 }
drh81a20f22001-10-12 17:30:04 +0000368
369end_playback:
drhd9b02572001-04-15 00:37:09 +0000370 if( rc!=SQLITE_OK ){
371 pager_unwritelock(pPager);
372 pPager->errMask |= PAGER_ERR_CORRUPT;
373 rc = SQLITE_CORRUPT;
374 }else{
375 rc = pager_unwritelock(pPager);
drhed7c8552001-04-11 14:29:21 +0000376 }
drhd9b02572001-04-15 00:37:09 +0000377 return rc;
drhed7c8552001-04-11 14:29:21 +0000378}
379
380/*
drhfa86c412002-02-02 15:01:15 +0000381** Playback the checkpoint journal.
382**
383** This is similar to playing back the transaction journal but with
384** a few extra twists.
385**
386** (1) The original size of the database file is stored in
387** pPager->ckptSize, not in the journal file itself.
388**
389** (2) In addition to playing back the checkpoint journal, also
390** playback all pages of the transaction journal beginning
391** at offset pPager->ckptJSize.
392*/
393static int pager_ckpt_playback(Pager *pPager){
394 int nRec; /* Number of Records */
395 int i; /* Loop counter */
396 int rc;
397
398 /* Truncate the database back to its original size.
399 */
400 rc = sqliteOsTruncate(&pPager->fd, pPager->ckptSize);
401 pPager->dbSize = pPager->ckptSize;
402
403 /* Figure out how many records are in the checkpoint journal.
404 */
405 assert( pPager->ckptOpen && pPager->journalOpen );
406 sqliteOsSeek(&pPager->cpfd, 0);
407 rc = sqliteOsFileSize(&pPager->cpfd, &nRec);
408 if( rc!=SQLITE_OK ){
409 goto end_ckpt_playback;
410 }
411 nRec /= sizeof(PageRecord);
412
413 /* Copy original pages out of the checkpoint journal and back into the
414 ** database file.
415 */
416 for(i=nRec-1; i>=0; i--){
417 rc = pager_playback_one_page(pPager, &pPager->cpfd);
418 if( rc!=SQLITE_OK ) goto end_ckpt_playback;
419 }
420
421 /* Figure out how many pages need to be copied out of the transaction
422 ** journal.
423 */
424 rc = sqliteOsSeek(&pPager->jfd, pPager->ckptJSize);
425 if( rc!=SQLITE_OK ){
426 goto end_ckpt_playback;
427 }
428 rc = sqliteOsFileSize(&pPager->jfd, &nRec);
429 if( rc!=SQLITE_OK ){
430 goto end_ckpt_playback;
431 }
432 nRec = (nRec - pPager->ckptJSize)/sizeof(PageRecord);
433 for(i=nRec-1; i>=0; i--){
434 rc = pager_playback_one_page(pPager, &pPager->jfd);
435 if( rc!=SQLITE_OK ) goto end_ckpt_playback;
436 }
437
438
439end_ckpt_playback:
440 sqliteOsClose(&pPager->cpfd);
441 pPager->ckptOpen = 0;
442 if( rc!=SQLITE_OK ){
443 pager_unwritelock(pPager);
444 pPager->errMask |= PAGER_ERR_CORRUPT;
445 rc = SQLITE_CORRUPT;
446 }else{
447 rc = pager_unwritelock(pPager);
448 }
449 return rc;
450}
451
452/*
drhf57b14a2001-09-14 18:54:08 +0000453** Change the maximum number of in-memory pages that are allowed.
454*/
455void sqlitepager_set_cachesize(Pager *pPager, int mxPage){
456 if( mxPage>10 ){
457 pPager->mxPage = mxPage;
458 }
459}
460
461/*
drhfa86c412002-02-02 15:01:15 +0000462** Open a temporary file. Write the name of the file into zName
463** (zName must be at least SQLITE_TEMPNAME_SIZE bytes long.) Write
464** the file descriptor into *fd. Return SQLITE_OK on success or some
465** other error code if we fail.
466**
467** The OS will automatically delete the temporary file when it is
468** closed.
469*/
470static int sqlitepager_opentemp(char *zFile, OsFile *fd){
471 int cnt = 8;
472 int rc;
473 do{
474 cnt--;
475 sqliteOsTempFileName(zFile);
476 rc = sqliteOsOpenExclusive(zFile, fd, 1);
477 }while( cnt>0 && rc!=SQLITE_OK );
478 return rc;
479}
480
481/*
drhed7c8552001-04-11 14:29:21 +0000482** Create a new page cache and put a pointer to the page cache in *ppPager.
drh5e00f6c2001-09-13 13:46:56 +0000483** The file to be cached need not exist. The file is not locked until
drhd9b02572001-04-15 00:37:09 +0000484** the first call to sqlitepager_get() and is only held open until the
485** last page is released using sqlitepager_unref().
drh382c0242001-10-06 16:33:02 +0000486**
drh6446c4d2001-12-15 14:22:18 +0000487** If zFilename is NULL then a randomly-named temporary file is created
488** and used as the file to be cached. The file will be deleted
489** automatically when it is closed.
drhed7c8552001-04-11 14:29:21 +0000490*/
drh7e3b0a02001-04-28 16:52:40 +0000491int sqlitepager_open(
492 Pager **ppPager, /* Return the Pager structure here */
493 const char *zFilename, /* Name of the database file to open */
494 int mxPage, /* Max number of in-memory cache pages */
495 int nExtra /* Extra bytes append to each in-memory page */
496){
drhed7c8552001-04-11 14:29:21 +0000497 Pager *pPager;
498 int nameLen;
drh8cfbf082001-09-19 13:22:39 +0000499 OsFile fd;
500 int rc;
drh5e00f6c2001-09-13 13:46:56 +0000501 int tempFile;
502 int readOnly = 0;
drh8cfbf082001-09-19 13:22:39 +0000503 char zTemp[SQLITE_TEMPNAME_SIZE];
drhed7c8552001-04-11 14:29:21 +0000504
drhd9b02572001-04-15 00:37:09 +0000505 *ppPager = 0;
506 if( sqlite_malloc_failed ){
507 return SQLITE_NOMEM;
508 }
drh5e00f6c2001-09-13 13:46:56 +0000509 if( zFilename ){
drh8cfbf082001-09-19 13:22:39 +0000510 rc = sqliteOsOpenReadWrite(zFilename, &fd, &readOnly);
drh5e00f6c2001-09-13 13:46:56 +0000511 tempFile = 0;
512 }else{
drhfa86c412002-02-02 15:01:15 +0000513 rc = sqlitepager_opentemp(zTemp, &fd);
drh5e00f6c2001-09-13 13:46:56 +0000514 zFilename = zTemp;
515 tempFile = 1;
516 }
drh8cfbf082001-09-19 13:22:39 +0000517 if( rc!=SQLITE_OK ){
drhed7c8552001-04-11 14:29:21 +0000518 return SQLITE_CANTOPEN;
519 }
520 nameLen = strlen(zFilename);
521 pPager = sqliteMalloc( sizeof(*pPager) + nameLen*2 + 30 );
drhd9b02572001-04-15 00:37:09 +0000522 if( pPager==0 ){
drha7fcb052001-12-14 15:09:55 +0000523 sqliteOsClose(&fd);
drhd9b02572001-04-15 00:37:09 +0000524 return SQLITE_NOMEM;
525 }
drhed7c8552001-04-11 14:29:21 +0000526 pPager->zFilename = (char*)&pPager[1];
527 pPager->zJournal = &pPager->zFilename[nameLen+1];
528 strcpy(pPager->zFilename, zFilename);
529 strcpy(pPager->zJournal, zFilename);
530 strcpy(&pPager->zJournal[nameLen], "-journal");
531 pPager->fd = fd;
drh8cfbf082001-09-19 13:22:39 +0000532 pPager->journalOpen = 0;
drhfa86c412002-02-02 15:01:15 +0000533 pPager->ckptOpen = 0;
drhed7c8552001-04-11 14:29:21 +0000534 pPager->nRef = 0;
535 pPager->dbSize = -1;
drhfa86c412002-02-02 15:01:15 +0000536 pPager->ckptSize = 0;
537 pPager->ckptJSize = 0;
drhed7c8552001-04-11 14:29:21 +0000538 pPager->nPage = 0;
drhd79caeb2001-04-15 02:27:24 +0000539 pPager->mxPage = mxPage>5 ? mxPage : 10;
drhed7c8552001-04-11 14:29:21 +0000540 pPager->state = SQLITE_UNLOCK;
drhd9b02572001-04-15 00:37:09 +0000541 pPager->errMask = 0;
drh5e00f6c2001-09-13 13:46:56 +0000542 pPager->tempFile = tempFile;
543 pPager->readOnly = readOnly;
drhf57b14a2001-09-14 18:54:08 +0000544 pPager->needSync = 0;
drhed7c8552001-04-11 14:29:21 +0000545 pPager->pFirst = 0;
546 pPager->pLast = 0;
drh7c717f72001-06-24 20:39:41 +0000547 pPager->nExtra = nExtra;
drhed7c8552001-04-11 14:29:21 +0000548 memset(pPager->aHash, 0, sizeof(pPager->aHash));
549 *ppPager = pPager;
550 return SQLITE_OK;
551}
552
553/*
drh72f82862001-05-24 21:06:34 +0000554** Set the destructor for this pager. If not NULL, the destructor is called
drh5e00f6c2001-09-13 13:46:56 +0000555** when the reference count on each page reaches zero. The destructor can
556** be used to clean up information in the extra segment appended to each page.
drh72f82862001-05-24 21:06:34 +0000557**
558** The destructor is not called as a result sqlitepager_close().
559** Destructors are only called by sqlitepager_unref().
560*/
561void sqlitepager_set_destructor(Pager *pPager, void (*xDesc)(void*)){
562 pPager->xDestructor = xDesc;
563}
564
565/*
drh5e00f6c2001-09-13 13:46:56 +0000566** Return the total number of pages in the disk file associated with
567** pPager.
drhed7c8552001-04-11 14:29:21 +0000568*/
drhd9b02572001-04-15 00:37:09 +0000569int sqlitepager_pagecount(Pager *pPager){
drhed7c8552001-04-11 14:29:21 +0000570 int n;
drhd9b02572001-04-15 00:37:09 +0000571 assert( pPager!=0 );
drhed7c8552001-04-11 14:29:21 +0000572 if( pPager->dbSize>=0 ){
573 return pPager->dbSize;
574 }
drha7fcb052001-12-14 15:09:55 +0000575 if( sqliteOsFileSize(&pPager->fd, &n)!=SQLITE_OK ){
drh81a20f22001-10-12 17:30:04 +0000576 pPager->errMask |= PAGER_ERR_DISK;
drh8cfbf082001-09-19 13:22:39 +0000577 return 0;
drhed7c8552001-04-11 14:29:21 +0000578 }
drh8cfbf082001-09-19 13:22:39 +0000579 n /= SQLITE_PAGE_SIZE;
drhd9b02572001-04-15 00:37:09 +0000580 if( pPager->state!=SQLITE_UNLOCK ){
drhed7c8552001-04-11 14:29:21 +0000581 pPager->dbSize = n;
582 }
583 return n;
584}
585
586/*
587** Shutdown the page cache. Free all memory and close all files.
588**
589** If a transaction was in progress when this routine is called, that
590** transaction is rolled back. All outstanding pages are invalidated
591** and their memory is freed. Any attempt to use a page associated
592** with this page cache after this function returns will likely
593** result in a coredump.
594*/
drhd9b02572001-04-15 00:37:09 +0000595int sqlitepager_close(Pager *pPager){
596 PgHdr *pPg, *pNext;
drhed7c8552001-04-11 14:29:21 +0000597 switch( pPager->state ){
drhfa86c412002-02-02 15:01:15 +0000598 case SQLITE_CHECKPOINT:
drhed7c8552001-04-11 14:29:21 +0000599 case SQLITE_WRITELOCK: {
drhd9b02572001-04-15 00:37:09 +0000600 sqlitepager_rollback(pPager);
drha7fcb052001-12-14 15:09:55 +0000601 sqliteOsUnlock(&pPager->fd);
drh8cfbf082001-09-19 13:22:39 +0000602 assert( pPager->journalOpen==0 );
drhed7c8552001-04-11 14:29:21 +0000603 break;
604 }
605 case SQLITE_READLOCK: {
drha7fcb052001-12-14 15:09:55 +0000606 sqliteOsUnlock(&pPager->fd);
drhed7c8552001-04-11 14:29:21 +0000607 break;
608 }
609 default: {
610 /* Do nothing */
611 break;
612 }
613 }
drhd9b02572001-04-15 00:37:09 +0000614 for(pPg=pPager->pAll; pPg; pPg=pNext){
615 pNext = pPg->pNextAll;
616 sqliteFree(pPg);
drhed7c8552001-04-11 14:29:21 +0000617 }
drha7fcb052001-12-14 15:09:55 +0000618 sqliteOsClose(&pPager->fd);
drh8cfbf082001-09-19 13:22:39 +0000619 assert( pPager->journalOpen==0 );
drh5e00f6c2001-09-13 13:46:56 +0000620 if( pPager->tempFile ){
drhfa86c412002-02-02 15:01:15 +0000621 /* sqliteOsDelete(pPager->zFilename); */
drh5e00f6c2001-09-13 13:46:56 +0000622 }
drhed7c8552001-04-11 14:29:21 +0000623 sqliteFree(pPager);
624 return SQLITE_OK;
625}
626
627/*
drh5e00f6c2001-09-13 13:46:56 +0000628** Return the page number for the given page data.
drhed7c8552001-04-11 14:29:21 +0000629*/
drhd9b02572001-04-15 00:37:09 +0000630Pgno sqlitepager_pagenumber(void *pData){
drhed7c8552001-04-11 14:29:21 +0000631 PgHdr *p = DATA_TO_PGHDR(pData);
632 return p->pgno;
633}
634
635/*
drh7e3b0a02001-04-28 16:52:40 +0000636** Increment the reference count for a page. If the page is
637** currently on the freelist (the reference count is zero) then
638** remove it from the freelist.
639*/
drhdf0b3b02001-06-23 11:36:20 +0000640static void page_ref(PgHdr *pPg){
drh7e3b0a02001-04-28 16:52:40 +0000641 if( pPg->nRef==0 ){
642 /* The page is currently on the freelist. Remove it. */
643 if( pPg->pPrevFree ){
644 pPg->pPrevFree->pNextFree = pPg->pNextFree;
645 }else{
646 pPg->pPager->pFirst = pPg->pNextFree;
647 }
648 if( pPg->pNextFree ){
649 pPg->pNextFree->pPrevFree = pPg->pPrevFree;
650 }else{
651 pPg->pPager->pLast = pPg->pPrevFree;
652 }
653 pPg->pPager->nRef++;
654 }
655 pPg->nRef++;
drhdd793422001-06-28 01:54:48 +0000656 REFINFO(pPg);
drhdf0b3b02001-06-23 11:36:20 +0000657}
658
659/*
660** Increment the reference count for a page. The input pointer is
661** a reference to the page data.
662*/
663int sqlitepager_ref(void *pData){
664 PgHdr *pPg = DATA_TO_PGHDR(pData);
665 page_ref(pPg);
drh8c42ca92001-06-22 19:15:00 +0000666 return SQLITE_OK;
drh7e3b0a02001-04-28 16:52:40 +0000667}
668
669/*
drhb19a2bc2001-09-16 00:13:26 +0000670** Sync the journal and then write all free dirty pages to the database
671** file.
672**
673** Writing all free dirty pages to the database after the sync is a
674** non-obvious optimization. fsync() is an expensive operation so we
drh6446c4d2001-12-15 14:22:18 +0000675** want to minimize the number it is called. After an fsync() call,
676** we are free to write dirty pages back to the database. It is best
677** to go ahead and write as many dirty pages as possible to minimize
678** the risk of having to do another fsync() later on. Writing dirty
679** free pages in this way was observed to make database operations go
680** up to 10 times faster.
drhfa86c412002-02-02 15:01:15 +0000681**
682** If we are writing to temporary database, there is no need to preserve
683** the integrity of the journal file, so we can save time and skip the
684** fsync().
drh50e5dad2001-09-15 00:57:28 +0000685*/
686static int syncAllPages(Pager *pPager){
687 PgHdr *pPg;
688 int rc = SQLITE_OK;
689 if( pPager->needSync ){
drhfa86c412002-02-02 15:01:15 +0000690 if( !pPager->tempFile ){
691 rc = sqliteOsSync(&pPager->jfd);
692 if( rc!=0 ) return rc;
693 }
drh50e5dad2001-09-15 00:57:28 +0000694 pPager->needSync = 0;
695 }
696 for(pPg=pPager->pFirst; pPg; pPg=pPg->pNextFree){
697 if( pPg->dirty ){
drha7fcb052001-12-14 15:09:55 +0000698 sqliteOsSeek(&pPager->fd, (pPg->pgno-1)*SQLITE_PAGE_SIZE);
699 rc = sqliteOsWrite(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
drh50e5dad2001-09-15 00:57:28 +0000700 if( rc!=SQLITE_OK ) break;
701 pPg->dirty = 0;
702 }
703 }
drh81a20f22001-10-12 17:30:04 +0000704 return rc;
drh50e5dad2001-09-15 00:57:28 +0000705}
706
707/*
drhd9b02572001-04-15 00:37:09 +0000708** Acquire a page.
709**
drh58a11682001-11-10 13:51:08 +0000710** A read lock on the disk file is obtained when the first page is acquired.
drh5e00f6c2001-09-13 13:46:56 +0000711** This read lock is dropped when the last page is released.
drhd9b02572001-04-15 00:37:09 +0000712**
drh306dc212001-05-21 13:45:10 +0000713** A _get works for any page number greater than 0. If the database
714** file is smaller than the requested page, then no actual disk
715** read occurs and the memory image of the page is initialized to
716** all zeros. The extra data appended to a page is always initialized
717** to zeros the first time a page is loaded into memory.
718**
drhd9b02572001-04-15 00:37:09 +0000719** The acquisition might fail for several reasons. In all cases,
720** an appropriate error code is returned and *ppPage is set to NULL.
drh7e3b0a02001-04-28 16:52:40 +0000721**
722** See also sqlitepager_lookup(). Both this routine and _lookup() attempt
723** to find a page in the in-memory cache first. If the page is not already
drh5e00f6c2001-09-13 13:46:56 +0000724** in memory, this routine goes to disk to read it in whereas _lookup()
drh7e3b0a02001-04-28 16:52:40 +0000725** just returns 0. This routine acquires a read-lock the first time it
726** has to go to disk, and could also playback an old journal if necessary.
727** Since _lookup() never goes to disk, it never has to deal with locks
728** or journal files.
drhed7c8552001-04-11 14:29:21 +0000729*/
drhd9b02572001-04-15 00:37:09 +0000730int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
drhed7c8552001-04-11 14:29:21 +0000731 PgHdr *pPg;
732
drhd9b02572001-04-15 00:37:09 +0000733 /* Make sure we have not hit any critical errors.
734 */
735 if( pPager==0 || pgno==0 ){
736 return SQLITE_ERROR;
737 }
738 if( pPager->errMask & ~(PAGER_ERR_FULL) ){
739 return pager_errcode(pPager);
740 }
741
drhed7c8552001-04-11 14:29:21 +0000742 /* If this is the first page accessed, then get a read lock
743 ** on the database file.
744 */
745 if( pPager->nRef==0 ){
drha7fcb052001-12-14 15:09:55 +0000746 if( sqliteOsReadLock(&pPager->fd)!=SQLITE_OK ){
drhed7c8552001-04-11 14:29:21 +0000747 *ppPage = 0;
748 return SQLITE_BUSY;
749 }
drhd9b02572001-04-15 00:37:09 +0000750 pPager->state = SQLITE_READLOCK;
drhed7c8552001-04-11 14:29:21 +0000751
752 /* If a journal file exists, try to play it back.
753 */
drh8cfbf082001-09-19 13:22:39 +0000754 if( sqliteOsFileExists(pPager->zJournal) ){
drhf57b3392001-10-08 13:22:32 +0000755 int rc, dummy;
drhed7c8552001-04-11 14:29:21 +0000756
drha7fcb052001-12-14 15:09:55 +0000757 /* Get a write lock on the database
758 */
759 rc = sqliteOsWriteLock(&pPager->fd);
760 if( rc!=SQLITE_OK ){
drh6446c4d2001-12-15 14:22:18 +0000761 rc = sqliteOsUnlock(&pPager->fd);
drha7fcb052001-12-14 15:09:55 +0000762 assert( rc==SQLITE_OK );
763 *ppPage = 0;
764 return SQLITE_BUSY;
765 }
766 pPager->state = SQLITE_WRITELOCK;
767
drhed7c8552001-04-11 14:29:21 +0000768 /* Open the journal for exclusive access. Return SQLITE_BUSY if
drhf57b3392001-10-08 13:22:32 +0000769 ** we cannot get exclusive access to the journal file.
770 **
771 ** Even though we will only be reading from the journal, not writing,
772 ** we have to open the journal for writing in order to obtain an
773 ** exclusive access lock.
drhed7c8552001-04-11 14:29:21 +0000774 */
drhf57b3392001-10-08 13:22:32 +0000775 rc = sqliteOsOpenReadWrite(pPager->zJournal, &pPager->jfd, &dummy);
drha7fcb052001-12-14 15:09:55 +0000776 if( rc!=SQLITE_OK ){
777 rc = sqliteOsUnlock(&pPager->fd);
778 assert( rc==SQLITE_OK );
drhed7c8552001-04-11 14:29:21 +0000779 *ppPage = 0;
780 return SQLITE_BUSY;
781 }
drha7fcb052001-12-14 15:09:55 +0000782 pPager->journalOpen = 1;
drhed7c8552001-04-11 14:29:21 +0000783
784 /* Playback and delete the journal. Drop the database write
785 ** lock and reacquire the read lock.
786 */
drhd9b02572001-04-15 00:37:09 +0000787 rc = pager_playback(pPager);
788 if( rc!=SQLITE_OK ){
789 return rc;
790 }
drhed7c8552001-04-11 14:29:21 +0000791 }
792 pPg = 0;
793 }else{
794 /* Search for page in cache */
drhd9b02572001-04-15 00:37:09 +0000795 pPg = pager_lookup(pPager, pgno);
drhed7c8552001-04-11 14:29:21 +0000796 }
797 if( pPg==0 ){
drhd9b02572001-04-15 00:37:09 +0000798 /* The requested page is not in the page cache. */
drhed7c8552001-04-11 14:29:21 +0000799 int h;
drh7e3b0a02001-04-28 16:52:40 +0000800 pPager->nMiss++;
drhed7c8552001-04-11 14:29:21 +0000801 if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 ){
802 /* Create a new page */
drh7e3b0a02001-04-28 16:52:40 +0000803 pPg = sqliteMalloc( sizeof(*pPg) + SQLITE_PAGE_SIZE + pPager->nExtra );
drhd9b02572001-04-15 00:37:09 +0000804 if( pPg==0 ){
805 *ppPage = 0;
806 pager_unwritelock(pPager);
807 pPager->errMask |= PAGER_ERR_MEM;
808 return SQLITE_NOMEM;
809 }
drhed7c8552001-04-11 14:29:21 +0000810 pPg->pPager = pPager;
drhd9b02572001-04-15 00:37:09 +0000811 pPg->pNextAll = pPager->pAll;
812 if( pPager->pAll ){
813 pPager->pAll->pPrevAll = pPg;
814 }
815 pPg->pPrevAll = 0;
drhd79caeb2001-04-15 02:27:24 +0000816 pPager->pAll = pPg;
drhd9b02572001-04-15 00:37:09 +0000817 pPager->nPage++;
drhed7c8552001-04-11 14:29:21 +0000818 }else{
drhd9b02572001-04-15 00:37:09 +0000819 /* Recycle an older page. First locate the page to be recycled.
820 ** Try to find one that is not dirty and is near the head of
821 ** of the free list */
drh50e5dad2001-09-15 00:57:28 +0000822 int cnt = pPager->mxPage/2;
drhed7c8552001-04-11 14:29:21 +0000823 pPg = pPager->pFirst;
drh6019e162001-07-02 17:51:45 +0000824 while( pPg->dirty && 0<cnt-- && pPg->pNextFree ){
drhd9b02572001-04-15 00:37:09 +0000825 pPg = pPg->pNextFree;
826 }
drhb19a2bc2001-09-16 00:13:26 +0000827
828 /* If we could not find a page that has not been used recently
829 ** and which is not dirty, then sync the journal and write all
830 ** dirty free pages into the database file, thus making them
831 ** clean pages and available for recycling.
832 **
833 ** We have to sync the journal before writing a page to the main
834 ** database. But syncing is a very slow operation. So after a
835 ** sync, it is best to write everything we can back to the main
836 ** database to minimize the risk of having to sync again in the
837 ** near future. That is way we write all dirty pages after a
838 ** sync.
839 */
drh50e5dad2001-09-15 00:57:28 +0000840 if( pPg==0 || pPg->dirty ){
841 int rc = syncAllPages(pPager);
842 if( rc!=0 ){
843 sqlitepager_rollback(pPager);
844 *ppPage = 0;
845 return SQLITE_IOERR;
846 }
847 pPg = pPager->pFirst;
848 }
drhd9b02572001-04-15 00:37:09 +0000849 assert( pPg->nRef==0 );
drh50e5dad2001-09-15 00:57:28 +0000850 assert( pPg->dirty==0 );
drhd9b02572001-04-15 00:37:09 +0000851
852 /* Unlink the old page from the free list and the hash table
853 */
drh6019e162001-07-02 17:51:45 +0000854 if( pPg->pPrevFree ){
855 pPg->pPrevFree->pNextFree = pPg->pNextFree;
drhed7c8552001-04-11 14:29:21 +0000856 }else{
drh6019e162001-07-02 17:51:45 +0000857 assert( pPager->pFirst==pPg );
858 pPager->pFirst = pPg->pNextFree;
drhed7c8552001-04-11 14:29:21 +0000859 }
drh6019e162001-07-02 17:51:45 +0000860 if( pPg->pNextFree ){
861 pPg->pNextFree->pPrevFree = pPg->pPrevFree;
862 }else{
863 assert( pPager->pLast==pPg );
864 pPager->pLast = pPg->pPrevFree;
865 }
866 pPg->pNextFree = pPg->pPrevFree = 0;
drhed7c8552001-04-11 14:29:21 +0000867 if( pPg->pNextHash ){
868 pPg->pNextHash->pPrevHash = pPg->pPrevHash;
869 }
870 if( pPg->pPrevHash ){
871 pPg->pPrevHash->pNextHash = pPg->pNextHash;
872 }else{
drhd9b02572001-04-15 00:37:09 +0000873 h = pager_hash(pPg->pgno);
drhed7c8552001-04-11 14:29:21 +0000874 assert( pPager->aHash[h]==pPg );
875 pPager->aHash[h] = pPg->pNextHash;
876 }
drh6019e162001-07-02 17:51:45 +0000877 pPg->pNextHash = pPg->pPrevHash = 0;
drhd9b02572001-04-15 00:37:09 +0000878 pPager->nOvfl++;
drhed7c8552001-04-11 14:29:21 +0000879 }
880 pPg->pgno = pgno;
drh1ab43002002-01-14 09:28:19 +0000881 if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
drh6019e162001-07-02 17:51:45 +0000882 pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0;
883 }else{
884 pPg->inJournal = 0;
885 }
drhfa86c412002-02-02 15:01:15 +0000886 if( pPager->aInCkpt && (int)pgno*SQLITE_PAGE_SIZE<=pPager->ckptSize ){
887 pPg->inCkpt = (pPager->aInCkpt[pgno/8] & (1<<(pgno&7)))!=0;
888 }else{
889 pPg->inCkpt = 0;
890 }
drhed7c8552001-04-11 14:29:21 +0000891 pPg->dirty = 0;
892 pPg->nRef = 1;
drhdd793422001-06-28 01:54:48 +0000893 REFINFO(pPg);
drhd9b02572001-04-15 00:37:09 +0000894 pPager->nRef++;
895 h = pager_hash(pgno);
drhed7c8552001-04-11 14:29:21 +0000896 pPg->pNextHash = pPager->aHash[h];
897 pPager->aHash[h] = pPg;
898 if( pPg->pNextHash ){
899 assert( pPg->pNextHash->pPrevHash==0 );
900 pPg->pNextHash->pPrevHash = pPg;
901 }
drh306dc212001-05-21 13:45:10 +0000902 if( pPager->dbSize<0 ) sqlitepager_pagecount(pPager);
drh1ab43002002-01-14 09:28:19 +0000903 if( pPager->dbSize<(int)pgno ){
drh306dc212001-05-21 13:45:10 +0000904 memset(PGHDR_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);
905 }else{
drh81a20f22001-10-12 17:30:04 +0000906 int rc;
drha7fcb052001-12-14 15:09:55 +0000907 sqliteOsSeek(&pPager->fd, (pgno-1)*SQLITE_PAGE_SIZE);
908 rc = sqliteOsRead(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
drh81a20f22001-10-12 17:30:04 +0000909 if( rc!=SQLITE_OK ){
910 return rc;
911 }
drh306dc212001-05-21 13:45:10 +0000912 }
drh7e3b0a02001-04-28 16:52:40 +0000913 if( pPager->nExtra>0 ){
914 memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
915 }
drhed7c8552001-04-11 14:29:21 +0000916 }else{
drhd9b02572001-04-15 00:37:09 +0000917 /* The requested page is in the page cache. */
drh7e3b0a02001-04-28 16:52:40 +0000918 pPager->nHit++;
drhdf0b3b02001-06-23 11:36:20 +0000919 page_ref(pPg);
drhed7c8552001-04-11 14:29:21 +0000920 }
921 *ppPage = PGHDR_TO_DATA(pPg);
922 return SQLITE_OK;
923}
924
925/*
drh7e3b0a02001-04-28 16:52:40 +0000926** Acquire a page if it is already in the in-memory cache. Do
927** not read the page from disk. Return a pointer to the page,
928** or 0 if the page is not in cache.
929**
930** See also sqlitepager_get(). The difference between this routine
931** and sqlitepager_get() is that _get() will go to the disk and read
932** in the page if the page is not already in cache. This routine
drh5e00f6c2001-09-13 13:46:56 +0000933** returns NULL if the page is not in cache or if a disk I/O error
934** has ever happened.
drh7e3b0a02001-04-28 16:52:40 +0000935*/
936void *sqlitepager_lookup(Pager *pPager, Pgno pgno){
937 PgHdr *pPg;
938
939 /* Make sure we have not hit any critical errors.
940 */
941 if( pPager==0 || pgno==0 ){
942 return 0;
943 }
944 if( pPager->errMask & ~(PAGER_ERR_FULL) ){
945 return 0;
946 }
947 if( pPager->nRef==0 ){
948 return 0;
949 }
950 pPg = pager_lookup(pPager, pgno);
951 if( pPg==0 ) return 0;
drhdf0b3b02001-06-23 11:36:20 +0000952 page_ref(pPg);
drh7e3b0a02001-04-28 16:52:40 +0000953 return PGHDR_TO_DATA(pPg);
954}
955
956/*
drhed7c8552001-04-11 14:29:21 +0000957** Release a page.
958**
959** If the number of references to the page drop to zero, then the
960** page is added to the LRU list. When all references to all pages
drhd9b02572001-04-15 00:37:09 +0000961** are released, a rollback occurs and the lock on the database is
drhed7c8552001-04-11 14:29:21 +0000962** removed.
963*/
drhd9b02572001-04-15 00:37:09 +0000964int sqlitepager_unref(void *pData){
drhed7c8552001-04-11 14:29:21 +0000965 PgHdr *pPg;
drhd9b02572001-04-15 00:37:09 +0000966
967 /* Decrement the reference count for this page
968 */
drhed7c8552001-04-11 14:29:21 +0000969 pPg = DATA_TO_PGHDR(pData);
970 assert( pPg->nRef>0 );
drhed7c8552001-04-11 14:29:21 +0000971 pPg->nRef--;
drhdd793422001-06-28 01:54:48 +0000972 REFINFO(pPg);
drhd9b02572001-04-15 00:37:09 +0000973
drh72f82862001-05-24 21:06:34 +0000974 /* When the number of references to a page reach 0, call the
975 ** destructor and add the page to the freelist.
drhd9b02572001-04-15 00:37:09 +0000976 */
drhed7c8552001-04-11 14:29:21 +0000977 if( pPg->nRef==0 ){
drh1eaa2692001-09-18 02:02:23 +0000978 Pager *pPager;
979 pPager = pPg->pPager;
drhd9b02572001-04-15 00:37:09 +0000980 pPg->pNextFree = 0;
981 pPg->pPrevFree = pPager->pLast;
drhed7c8552001-04-11 14:29:21 +0000982 pPager->pLast = pPg;
drhd9b02572001-04-15 00:37:09 +0000983 if( pPg->pPrevFree ){
984 pPg->pPrevFree->pNextFree = pPg;
drhed7c8552001-04-11 14:29:21 +0000985 }else{
986 pPager->pFirst = pPg;
987 }
drh72f82862001-05-24 21:06:34 +0000988 if( pPager->xDestructor ){
989 pPager->xDestructor(pData);
990 }
drhd9b02572001-04-15 00:37:09 +0000991
992 /* When all pages reach the freelist, drop the read lock from
993 ** the database file.
994 */
995 pPager->nRef--;
996 assert( pPager->nRef>=0 );
997 if( pPager->nRef==0 ){
998 pager_reset(pPager);
999 }
drhed7c8552001-04-11 14:29:21 +00001000 }
drhd9b02572001-04-15 00:37:09 +00001001 return SQLITE_OK;
drhed7c8552001-04-11 14:29:21 +00001002}
1003
1004/*
1005** Mark a data page as writeable. The page is written into the journal
1006** if it is not there already. This routine must be called before making
1007** changes to a page.
1008**
1009** The first time this routine is called, the pager creates a new
1010** journal and acquires a write lock on the database. If the write
1011** lock could not be acquired, this routine returns SQLITE_BUSY. The
drh306dc212001-05-21 13:45:10 +00001012** calling routine must check for that return value and be careful not to
drhed7c8552001-04-11 14:29:21 +00001013** change any page data until this routine returns SQLITE_OK.
drhd9b02572001-04-15 00:37:09 +00001014**
1015** If the journal file could not be written because the disk is full,
1016** then this routine returns SQLITE_FULL and does an immediate rollback.
1017** All subsequent write attempts also return SQLITE_FULL until there
1018** is a call to sqlitepager_commit() or sqlitepager_rollback() to
1019** reset.
drhed7c8552001-04-11 14:29:21 +00001020*/
drhd9b02572001-04-15 00:37:09 +00001021int sqlitepager_write(void *pData){
drh69688d52001-04-14 16:38:23 +00001022 PgHdr *pPg = DATA_TO_PGHDR(pData);
1023 Pager *pPager = pPg->pPager;
drhd79caeb2001-04-15 02:27:24 +00001024 int rc = SQLITE_OK;
drh69688d52001-04-14 16:38:23 +00001025
drh6446c4d2001-12-15 14:22:18 +00001026 /* Check for errors
1027 */
drhd9b02572001-04-15 00:37:09 +00001028 if( pPager->errMask ){
1029 return pager_errcode(pPager);
1030 }
drh5e00f6c2001-09-13 13:46:56 +00001031 if( pPager->readOnly ){
1032 return SQLITE_PERM;
1033 }
drh6446c4d2001-12-15 14:22:18 +00001034
1035 /* Mark the page as dirty. If the page has already been written
1036 ** to the journal then we can return right away.
1037 */
drhd9b02572001-04-15 00:37:09 +00001038 pPg->dirty = 1;
drhfa86c412002-02-02 15:01:15 +00001039 if( pPg->inJournal && (pPg->inCkpt || pPager->ckptOpen==0) ){
1040 return SQLITE_OK;
1041 }
drh6446c4d2001-12-15 14:22:18 +00001042
1043 /* If we get this far, it means that the page needs to be
drhfa86c412002-02-02 15:01:15 +00001044 ** written to the transaction journal or the ckeckpoint journal
1045 ** or both.
1046 **
1047 ** First check to see that the transaction journal exists and
1048 ** create it if it does not.
drh6446c4d2001-12-15 14:22:18 +00001049 */
drhd9b02572001-04-15 00:37:09 +00001050 assert( pPager->state!=SQLITE_UNLOCK );
drhed7c8552001-04-11 14:29:21 +00001051 if( pPager->state==SQLITE_READLOCK ){
drh6019e162001-07-02 17:51:45 +00001052 assert( pPager->aInJournal==0 );
drha7fcb052001-12-14 15:09:55 +00001053 rc = sqliteOsWriteLock(&pPager->fd);
1054 if( rc!=SQLITE_OK ){
1055 return rc;
1056 }
drh6019e162001-07-02 17:51:45 +00001057 pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 );
1058 if( pPager->aInJournal==0 ){
drha7fcb052001-12-14 15:09:55 +00001059 sqliteOsReadLock(&pPager->fd);
drh6019e162001-07-02 17:51:45 +00001060 return SQLITE_NOMEM;
1061 }
drhfa86c412002-02-02 15:01:15 +00001062 rc = sqliteOsOpenExclusive(pPager->zJournal, &pPager->jfd, 0);
drh8cfbf082001-09-19 13:22:39 +00001063 if( rc!=SQLITE_OK ){
drh6d4abfb2001-10-22 02:58:08 +00001064 sqliteFree(pPager->aInJournal);
drha7fcb052001-12-14 15:09:55 +00001065 pPager->aInJournal = 0;
1066 sqliteOsReadLock(&pPager->fd);
drhed7c8552001-04-11 14:29:21 +00001067 return SQLITE_CANTOPEN;
1068 }
drh8cfbf082001-09-19 13:22:39 +00001069 pPager->journalOpen = 1;
drhf57b14a2001-09-14 18:54:08 +00001070 pPager->needSync = 0;
drhed7c8552001-04-11 14:29:21 +00001071 pPager->state = SQLITE_WRITELOCK;
drhd9b02572001-04-15 00:37:09 +00001072 sqlitepager_pagecount(pPager);
drh69688d52001-04-14 16:38:23 +00001073 pPager->origDbSize = pPager->dbSize;
drha7fcb052001-12-14 15:09:55 +00001074 rc = sqliteOsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic));
drhd9b02572001-04-15 00:37:09 +00001075 if( rc==SQLITE_OK ){
drha7fcb052001-12-14 15:09:55 +00001076 rc = sqliteOsWrite(&pPager->jfd, &pPager->dbSize, sizeof(Pgno));
drhd9b02572001-04-15 00:37:09 +00001077 }
1078 if( rc!=SQLITE_OK ){
1079 rc = pager_unwritelock(pPager);
1080 if( rc==SQLITE_OK ) rc = SQLITE_FULL;
1081 return rc;
1082 }
drhed7c8552001-04-11 14:29:21 +00001083 }
drhd9b02572001-04-15 00:37:09 +00001084 assert( pPager->state==SQLITE_WRITELOCK );
drh8cfbf082001-09-19 13:22:39 +00001085 assert( pPager->journalOpen );
drh6446c4d2001-12-15 14:22:18 +00001086
drhfa86c412002-02-02 15:01:15 +00001087 /* The transaction journal now exists and we have a write lock on the
1088 ** main database file. Write the current page to the transaction
1089 ** journal if it is not there already.
drh6446c4d2001-12-15 14:22:18 +00001090 */
drhfa86c412002-02-02 15:01:15 +00001091 if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
drha7fcb052001-12-14 15:09:55 +00001092 rc = sqliteOsWrite(&pPager->jfd, &pPg->pgno, sizeof(Pgno));
drhd9b02572001-04-15 00:37:09 +00001093 if( rc==SQLITE_OK ){
drha7fcb052001-12-14 15:09:55 +00001094 rc = sqliteOsWrite(&pPager->jfd, pData, SQLITE_PAGE_SIZE);
drhd9b02572001-04-15 00:37:09 +00001095 }
1096 if( rc!=SQLITE_OK ){
1097 sqlitepager_rollback(pPager);
1098 pPager->errMask |= PAGER_ERR_FULL;
1099 return rc;
1100 }
drh6019e162001-07-02 17:51:45 +00001101 assert( pPager->aInJournal!=0 );
1102 pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
drhf57b14a2001-09-14 18:54:08 +00001103 pPager->needSync = 1;
drhfa86c412002-02-02 15:01:15 +00001104 pPg->inJournal = 1;
1105 if( pPager->ckptOpen ){
1106 pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
1107 pPg->inCkpt = 1;
1108 }
drh69688d52001-04-14 16:38:23 +00001109 }
drh6446c4d2001-12-15 14:22:18 +00001110
drhfa86c412002-02-02 15:01:15 +00001111 /* If the checkpoint journal is open and the page is not in it,
1112 ** then write the current page to the checkpoint journal.
drh6446c4d2001-12-15 14:22:18 +00001113 */
drhfa86c412002-02-02 15:01:15 +00001114 if( pPager->ckptOpen && !pPg->inCkpt
1115 && (int)pPg->pgno*SQLITE_PAGE_SIZE < pPager->ckptSize ){
1116 assert( pPg->inJournal );
1117 rc = sqliteOsWrite(&pPager->cpfd, &pPg->pgno, sizeof(Pgno));
1118 if( rc==SQLITE_OK ){
1119 rc = sqliteOsWrite(&pPager->cpfd, pData, SQLITE_PAGE_SIZE);
1120 }
1121 if( rc!=SQLITE_OK ){
1122 sqlitepager_rollback(pPager);
1123 pPager->errMask |= PAGER_ERR_FULL;
1124 return rc;
1125 }
1126 assert( pPager->aInCkpt!=0 );
1127 pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
1128 pPg->inCkpt = 1;
1129 }
1130
1131 /* Update the database size and return.
1132 */
drh1ab43002002-01-14 09:28:19 +00001133 if( pPager->dbSize<(int)pPg->pgno ){
drh306dc212001-05-21 13:45:10 +00001134 pPager->dbSize = pPg->pgno;
1135 }
drh69688d52001-04-14 16:38:23 +00001136 return rc;
drhed7c8552001-04-11 14:29:21 +00001137}
1138
1139/*
drhaacc5432002-01-06 17:07:40 +00001140** Return TRUE if the page given in the argument was previously passed
drh6019e162001-07-02 17:51:45 +00001141** to sqlitepager_write(). In other words, return TRUE if it is ok
1142** to change the content of the page.
1143*/
1144int sqlitepager_iswriteable(void *pData){
1145 PgHdr *pPg = DATA_TO_PGHDR(pData);
1146 return pPg->dirty;
1147}
1148
1149/*
drhed7c8552001-04-11 14:29:21 +00001150** Commit all changes to the database and release the write lock.
drhd9b02572001-04-15 00:37:09 +00001151**
1152** If the commit fails for any reason, a rollback attempt is made
1153** and an error code is returned. If the commit worked, SQLITE_OK
1154** is returned.
drhed7c8552001-04-11 14:29:21 +00001155*/
drhd9b02572001-04-15 00:37:09 +00001156int sqlitepager_commit(Pager *pPager){
drha1b351a2001-09-14 16:42:12 +00001157 int rc;
drhed7c8552001-04-11 14:29:21 +00001158 PgHdr *pPg;
drhd9b02572001-04-15 00:37:09 +00001159
1160 if( pPager->errMask==PAGER_ERR_FULL ){
1161 rc = sqlitepager_rollback(pPager);
1162 if( rc==SQLITE_OK ) rc = SQLITE_FULL;
1163 return rc;
1164 }
1165 if( pPager->errMask!=0 ){
1166 rc = pager_errcode(pPager);
1167 return rc;
1168 }
1169 if( pPager->state!=SQLITE_WRITELOCK ){
1170 return SQLITE_ERROR;
1171 }
drh8cfbf082001-09-19 13:22:39 +00001172 assert( pPager->journalOpen );
drha7fcb052001-12-14 15:09:55 +00001173 if( pPager->needSync && sqliteOsSync(&pPager->jfd)!=SQLITE_OK ){
drhd9b02572001-04-15 00:37:09 +00001174 goto commit_abort;
drhed7c8552001-04-11 14:29:21 +00001175 }
drha1b351a2001-09-14 16:42:12 +00001176 for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
1177 if( pPg->dirty==0 ) continue;
drha7fcb052001-12-14 15:09:55 +00001178 rc = sqliteOsSeek(&pPager->fd, (pPg->pgno-1)*SQLITE_PAGE_SIZE);
drha1b351a2001-09-14 16:42:12 +00001179 if( rc!=SQLITE_OK ) goto commit_abort;
drha7fcb052001-12-14 15:09:55 +00001180 rc = sqliteOsWrite(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
drha1b351a2001-09-14 16:42:12 +00001181 if( rc!=SQLITE_OK ) goto commit_abort;
drhed7c8552001-04-11 14:29:21 +00001182 }
drha7fcb052001-12-14 15:09:55 +00001183 if( sqliteOsSync(&pPager->fd)!=SQLITE_OK ) goto commit_abort;
drhd9b02572001-04-15 00:37:09 +00001184 rc = pager_unwritelock(pPager);
1185 pPager->dbSize = -1;
1186 return rc;
1187
1188 /* Jump here if anything goes wrong during the commit process.
1189 */
1190commit_abort:
1191 rc = sqlitepager_rollback(pPager);
1192 if( rc==SQLITE_OK ){
1193 rc = SQLITE_FULL;
drhed7c8552001-04-11 14:29:21 +00001194 }
drhed7c8552001-04-11 14:29:21 +00001195 return rc;
1196}
1197
1198/*
1199** Rollback all changes. The database falls back to read-only mode.
1200** All in-memory cache pages revert to their original data contents.
1201** The journal is deleted.
drhd9b02572001-04-15 00:37:09 +00001202**
1203** This routine cannot fail unless some other process is not following
1204** the correct locking protocol (SQLITE_PROTOCOL) or unless some other
1205** process is writing trash into the journal file (SQLITE_CORRUPT) or
1206** unless a prior malloc() failed (SQLITE_NOMEM). Appropriate error
1207** codes are returned for all these occasions. Otherwise,
1208** SQLITE_OK is returned.
drhed7c8552001-04-11 14:29:21 +00001209*/
drhd9b02572001-04-15 00:37:09 +00001210int sqlitepager_rollback(Pager *pPager){
drhed7c8552001-04-11 14:29:21 +00001211 int rc;
drhd9b02572001-04-15 00:37:09 +00001212 if( pPager->errMask!=0 && pPager->errMask!=PAGER_ERR_FULL ){
1213 return pager_errcode(pPager);
drhed7c8552001-04-11 14:29:21 +00001214 }
drhd9b02572001-04-15 00:37:09 +00001215 if( pPager->state!=SQLITE_WRITELOCK ){
1216 return SQLITE_OK;
1217 }
1218 rc = pager_playback(pPager);
1219 if( rc!=SQLITE_OK ){
1220 rc = SQLITE_CORRUPT;
1221 pPager->errMask |= PAGER_ERR_CORRUPT;
1222 }
1223 pPager->dbSize = -1;
drhed7c8552001-04-11 14:29:21 +00001224 return rc;
drh98808ba2001-10-18 12:34:46 +00001225}
drhd9b02572001-04-15 00:37:09 +00001226
1227/*
drh5e00f6c2001-09-13 13:46:56 +00001228** Return TRUE if the database file is opened read-only. Return FALSE
1229** if the database is (in theory) writable.
1230*/
1231int sqlitepager_isreadonly(Pager *pPager){
drhbe0072d2001-09-13 14:46:09 +00001232 return pPager->readOnly;
drh5e00f6c2001-09-13 13:46:56 +00001233}
1234
1235/*
drhd9b02572001-04-15 00:37:09 +00001236** This routine is used for testing and analysis only.
1237*/
1238int *sqlitepager_stats(Pager *pPager){
1239 static int a[9];
1240 a[0] = pPager->nRef;
1241 a[1] = pPager->nPage;
1242 a[2] = pPager->mxPage;
1243 a[3] = pPager->dbSize;
1244 a[4] = pPager->state;
1245 a[5] = pPager->errMask;
1246 a[6] = pPager->nHit;
1247 a[7] = pPager->nMiss;
1248 a[8] = pPager->nOvfl;
1249 return a;
1250}
drhdd793422001-06-28 01:54:48 +00001251
drhfa86c412002-02-02 15:01:15 +00001252/*
1253** Set the checkpoint.
1254**
1255** This routine should be called with the transaction journal already
1256** open. A new checkpoint journal is created that can be used to rollback
1257** changes of a single command within a larger transaction.
1258*/
1259int sqlitepager_ckpt_begin(Pager *pPager){
1260 int rc;
1261 char zTemp[SQLITE_TEMPNAME_SIZE];
1262 assert( pPager->journalOpen );
1263 assert( !pPager->ckptOpen );
1264 pPager->aInCkpt = sqliteMalloc( pPager->dbSize/8 + 1 );
1265 if( pPager->aInCkpt==0 ){
1266 sqliteOsReadLock(&pPager->fd);
1267 return SQLITE_NOMEM;
1268 }
1269 rc = sqliteOsFileSize(&pPager->jfd, &pPager->ckptJSize);
1270 if( rc ) goto ckpt_begin_failed;
1271 pPager->ckptSize = pPager->dbSize * SQLITE_PAGE_SIZE;
1272 rc = sqlitepager_opentemp(zTemp, &pPager->cpfd);
1273 if( rc ) goto ckpt_begin_failed;
1274 pPager->ckptOpen = 1;
1275 return SQLITE_OK;
1276
1277ckpt_begin_failed:
1278 if( pPager->aInCkpt ){
1279 sqliteFree(pPager->aInCkpt);
1280 pPager->aInCkpt = 0;
1281 }
1282 return rc;
1283}
1284
1285/*
1286** Commit a checkpoint.
1287*/
1288int sqlitepager_ckpt_commit(Pager *pPager){
1289 assert( pPager->ckptOpen );
1290 sqliteOsClose(&pPager->cpfd);
1291 sqliteFree(pPager->aInCkpt);
1292 pPager->ckptOpen = 0;
1293 return SQLITE_OK;
1294}
1295
1296/*
1297** Rollback a checkpoint.
1298*/
1299int sqlitepager_ckpt_rollback(Pager *pPager){
1300 int rc;
1301 assert( pPager->ckptOpen );
1302 rc = pager_ckpt_playback(pPager);
1303 sqliteOsClose(&pPager->cpfd);
1304 sqliteFree(pPager->aInCkpt);
1305 pPager->ckptOpen = 0;
1306 return rc;
1307}
1308
drhdd793422001-06-28 01:54:48 +00001309#if SQLITE_TEST
1310/*
1311** Print a listing of all referenced pages and their ref count.
1312*/
1313void sqlitepager_refdump(Pager *pPager){
1314 PgHdr *pPg;
1315 for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
1316 if( pPg->nRef<=0 ) continue;
1317 printf("PAGE %3d addr=0x%08x nRef=%d\n",
1318 pPg->pgno, (int)PGHDR_TO_DATA(pPg), pPg->nRef);
1319 }
1320}
1321#endif