blob: d4fe1852de06bc980765577a4916f6d8ed81b5a6 [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**
drh663fc632002-02-02 18:49:19 +000021** @(#) $Id: pager.c,v 1.38 2002/02/02 18:49:20 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**
drh306dc212001-05-21 13:45:10 +000048** The page cache comes up in SQLITE_UNLOCK. The first time a
49** sqlite_page_get() occurs, the state transitions to SQLITE_READLOCK.
drhed7c8552001-04-11 14:29:21 +000050** After all pages have been released using sqlite_page_unref(),
drh306dc212001-05-21 13:45:10 +000051** the state transitions back to SQLITE_UNLOCK. The first time
drhed7c8552001-04-11 14:29:21 +000052** that sqlite_page_write() is called, the state transitions to
drh306dc212001-05-21 13:45:10 +000053** SQLITE_WRITELOCK. (Note that sqlite_page_write() can only be
54** called on an outstanding page which means that the pager must
55** be in SQLITE_READLOCK before it transitions to SQLITE_WRITELOCK.)
56** The sqlite_page_rollback() and sqlite_page_commit() functions
57** transition the state from SQLITE_WRITELOCK back to SQLITE_READLOCK.
drhed7c8552001-04-11 14:29:21 +000058*/
59#define SQLITE_UNLOCK 0
60#define SQLITE_READLOCK 1
61#define SQLITE_WRITELOCK 2
62
drhd9b02572001-04-15 00:37:09 +000063
drhed7c8552001-04-11 14:29:21 +000064/*
65** Each in-memory image of a page begins with the following header.
drhbd03cae2001-06-02 02:40:57 +000066** This header is only visible to this pager module. The client
67** code that calls pager sees only the data that follows the header.
drhed7c8552001-04-11 14:29:21 +000068*/
drhd9b02572001-04-15 00:37:09 +000069typedef struct PgHdr PgHdr;
drhed7c8552001-04-11 14:29:21 +000070struct PgHdr {
71 Pager *pPager; /* The pager to which this page belongs */
72 Pgno pgno; /* The page number for this page */
drh69688d52001-04-14 16:38:23 +000073 PgHdr *pNextHash, *pPrevHash; /* Hash collision chain for PgHdr.pgno */
drhed7c8552001-04-11 14:29:21 +000074 int nRef; /* Number of users of this page */
drhd9b02572001-04-15 00:37:09 +000075 PgHdr *pNextFree, *pPrevFree; /* Freelist of pages where nRef==0 */
76 PgHdr *pNextAll, *pPrevAll; /* A list of all pages */
drhed7c8552001-04-11 14:29:21 +000077 char inJournal; /* TRUE if has been written to journal */
drhfa86c412002-02-02 15:01:15 +000078 char inCkpt; /* TRUE if written to the checkpoint journal */
drhed7c8552001-04-11 14:29:21 +000079 char dirty; /* TRUE if we need to write back changes */
drh69688d52001-04-14 16:38:23 +000080 /* SQLITE_PAGE_SIZE bytes of page data follow this header */
drh7e3b0a02001-04-28 16:52:40 +000081 /* Pager.nExtra bytes of local data follow the page data */
drhed7c8552001-04-11 14:29:21 +000082};
83
84/*
drh69688d52001-04-14 16:38:23 +000085** Convert a pointer to a PgHdr into a pointer to its data
86** and back again.
drhed7c8552001-04-11 14:29:21 +000087*/
88#define PGHDR_TO_DATA(P) ((void*)(&(P)[1]))
89#define DATA_TO_PGHDR(D) (&((PgHdr*)(D))[-1])
drh7e3b0a02001-04-28 16:52:40 +000090#define PGHDR_TO_EXTRA(P) ((void*)&((char*)(&(P)[1]))[SQLITE_PAGE_SIZE])
drhed7c8552001-04-11 14:29:21 +000091
92/*
drhed7c8552001-04-11 14:29:21 +000093** How big to make the hash table used for locating in-memory pages
drh306dc212001-05-21 13:45:10 +000094** by page number. Knuth says this should be a prime number.
drhed7c8552001-04-11 14:29:21 +000095*/
drhb19a2bc2001-09-16 00:13:26 +000096#define N_PG_HASH 373
drhed7c8552001-04-11 14:29:21 +000097
98/*
99** A open page cache is an instance of the following structure.
100*/
101struct Pager {
102 char *zFilename; /* Name of the database file */
103 char *zJournal; /* Name of the journal file */
drh8cfbf082001-09-19 13:22:39 +0000104 OsFile fd, jfd; /* File descriptors for database and journal */
drhfa86c412002-02-02 15:01:15 +0000105 OsFile cpfd; /* File descriptor for the checkpoint journal */
drh8cfbf082001-09-19 13:22:39 +0000106 int journalOpen; /* True if journal file descriptors is valid */
drhfa86c412002-02-02 15:01:15 +0000107 int ckptOpen; /* True if the checkpoint journal is open */
drhed7c8552001-04-11 14:29:21 +0000108 int dbSize; /* Number of pages in the file */
drh69688d52001-04-14 16:38:23 +0000109 int origDbSize; /* dbSize before the current change */
drhfa86c412002-02-02 15:01:15 +0000110 int ckptSize, ckptJSize; /* Size of database and journal at ckpt_begin() */
drh7e3b0a02001-04-28 16:52:40 +0000111 int nExtra; /* Add this many bytes to each in-memory page */
drh72f82862001-05-24 21:06:34 +0000112 void (*xDestructor)(void*); /* Call this routine when freeing pages */
drhed7c8552001-04-11 14:29:21 +0000113 int nPage; /* Total number of in-memory pages */
drhd9b02572001-04-15 00:37:09 +0000114 int nRef; /* Number of in-memory pages with PgHdr.nRef>0 */
drhed7c8552001-04-11 14:29:21 +0000115 int mxPage; /* Maximum number of pages to hold in cache */
drhd9b02572001-04-15 00:37:09 +0000116 int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */
117 unsigned char state; /* SQLITE_UNLOCK, _READLOCK or _WRITELOCK */
118 unsigned char errMask; /* One of several kinds of errors */
drh5e00f6c2001-09-13 13:46:56 +0000119 unsigned char tempFile; /* zFilename is a temporary file */
120 unsigned char readOnly; /* True for a read-only database */
drhf57b14a2001-09-14 18:54:08 +0000121 unsigned char needSync; /* True if an fsync() is needed on the journal */
drh6019e162001-07-02 17:51:45 +0000122 unsigned char *aInJournal; /* One bit for each page in the database file */
drhfa86c412002-02-02 15:01:15 +0000123 unsigned char *aInCkpt; /* One bit for each page in the database */
drhed7c8552001-04-11 14:29:21 +0000124 PgHdr *pFirst, *pLast; /* List of free pages */
drhd9b02572001-04-15 00:37:09 +0000125 PgHdr *pAll; /* List of all pages */
drhed7c8552001-04-11 14:29:21 +0000126 PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number of PgHdr */
drhd9b02572001-04-15 00:37:09 +0000127};
128
129/*
130** These are bits that can be set in Pager.errMask.
131*/
132#define PAGER_ERR_FULL 0x01 /* a write() failed */
133#define PAGER_ERR_MEM 0x02 /* malloc() failed */
134#define PAGER_ERR_LOCK 0x04 /* error in the locking protocol */
135#define PAGER_ERR_CORRUPT 0x08 /* database or journal corruption */
drh81a20f22001-10-12 17:30:04 +0000136#define PAGER_ERR_DISK 0x10 /* general disk I/O error - bad hard drive? */
drhd9b02572001-04-15 00:37:09 +0000137
138/*
139** The journal file contains page records in the following
140** format.
141*/
142typedef struct PageRecord PageRecord;
143struct PageRecord {
144 Pgno pgno; /* The page number */
145 char aData[SQLITE_PAGE_SIZE]; /* Original data for page pgno */
146};
147
148/*
drh5e00f6c2001-09-13 13:46:56 +0000149** Journal files begin with the following magic string. The data
150** was obtained from /dev/random. It is used only as a sanity check.
drhd9b02572001-04-15 00:37:09 +0000151*/
152static const unsigned char aJournalMagic[] = {
153 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd4,
drhed7c8552001-04-11 14:29:21 +0000154};
155
156/*
157** Hash a page number
158*/
drhd9b02572001-04-15 00:37:09 +0000159#define pager_hash(PN) ((PN)%N_PG_HASH)
drhed7c8552001-04-11 14:29:21 +0000160
161/*
drhdd793422001-06-28 01:54:48 +0000162** Enable reference count tracking here:
163*/
164#if SQLITE_TEST
drh5e00f6c2001-09-13 13:46:56 +0000165 int pager_refinfo_enable = 0;
drhdd793422001-06-28 01:54:48 +0000166 static void pager_refinfo(PgHdr *p){
167 static int cnt = 0;
168 if( !pager_refinfo_enable ) return;
169 printf(
170 "REFCNT: %4d addr=0x%08x nRef=%d\n",
171 p->pgno, (int)PGHDR_TO_DATA(p), p->nRef
172 );
173 cnt++; /* Something to set a breakpoint on */
174 }
175# define REFINFO(X) pager_refinfo(X)
176#else
177# define REFINFO(X)
178#endif
179
180/*
drhd9b02572001-04-15 00:37:09 +0000181** Convert the bits in the pPager->errMask into an approprate
182** return code.
183*/
184static int pager_errcode(Pager *pPager){
185 int rc = SQLITE_OK;
186 if( pPager->errMask & PAGER_ERR_LOCK ) rc = SQLITE_PROTOCOL;
drh81a20f22001-10-12 17:30:04 +0000187 if( pPager->errMask & PAGER_ERR_DISK ) rc = SQLITE_IOERR;
drhd9b02572001-04-15 00:37:09 +0000188 if( pPager->errMask & PAGER_ERR_FULL ) rc = SQLITE_FULL;
189 if( pPager->errMask & PAGER_ERR_MEM ) rc = SQLITE_NOMEM;
190 if( pPager->errMask & PAGER_ERR_CORRUPT ) rc = SQLITE_CORRUPT;
191 return rc;
drhed7c8552001-04-11 14:29:21 +0000192}
193
194/*
195** Find a page in the hash table given its page number. Return
196** a pointer to the page or NULL if not found.
197*/
drhd9b02572001-04-15 00:37:09 +0000198static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
drhed7c8552001-04-11 14:29:21 +0000199 PgHdr *p = pPager->aHash[pgno % N_PG_HASH];
200 while( p && p->pgno!=pgno ){
201 p = p->pNextHash;
202 }
203 return p;
204}
205
206/*
207** Unlock the database and clear the in-memory cache. This routine
208** sets the state of the pager back to what it was when it was first
209** opened. Any outstanding pages are invalidated and subsequent attempts
210** to access those pages will likely result in a coredump.
211*/
drhd9b02572001-04-15 00:37:09 +0000212static void pager_reset(Pager *pPager){
drhed7c8552001-04-11 14:29:21 +0000213 PgHdr *pPg, *pNext;
drhd9b02572001-04-15 00:37:09 +0000214 for(pPg=pPager->pAll; pPg; pPg=pNext){
215 pNext = pPg->pNextAll;
216 sqliteFree(pPg);
drhed7c8552001-04-11 14:29:21 +0000217 }
218 pPager->pFirst = 0;
drhd9b02572001-04-15 00:37:09 +0000219 pPager->pLast = 0;
220 pPager->pAll = 0;
drhed7c8552001-04-11 14:29:21 +0000221 memset(pPager->aHash, 0, sizeof(pPager->aHash));
222 pPager->nPage = 0;
drhfa86c412002-02-02 15:01:15 +0000223 if( pPager->state>=SQLITE_WRITELOCK ){
drhd9b02572001-04-15 00:37:09 +0000224 sqlitepager_rollback(pPager);
drhed7c8552001-04-11 14:29:21 +0000225 }
drha7fcb052001-12-14 15:09:55 +0000226 sqliteOsUnlock(&pPager->fd);
drhed7c8552001-04-11 14:29:21 +0000227 pPager->state = SQLITE_UNLOCK;
drhd9b02572001-04-15 00:37:09 +0000228 pPager->dbSize = -1;
drhed7c8552001-04-11 14:29:21 +0000229 pPager->nRef = 0;
drh8cfbf082001-09-19 13:22:39 +0000230 assert( pPager->journalOpen==0 );
drhed7c8552001-04-11 14:29:21 +0000231}
232
233/*
234** When this routine is called, the pager has the journal file open and
235** a write lock on the database. This routine releases the database
236** write lock and acquires a read lock in its place. The journal file
237** is deleted and closed.
drhed7c8552001-04-11 14:29:21 +0000238*/
drhd9b02572001-04-15 00:37:09 +0000239static int pager_unwritelock(Pager *pPager){
drhed7c8552001-04-11 14:29:21 +0000240 int rc;
drhd9b02572001-04-15 00:37:09 +0000241 PgHdr *pPg;
drhfa86c412002-02-02 15:01:15 +0000242 if( pPager->state<SQLITE_WRITELOCK ) return SQLITE_OK;
drh663fc632002-02-02 18:49:19 +0000243 sqlitepager_ckpt_commit(pPager);
drha7fcb052001-12-14 15:09:55 +0000244 sqliteOsClose(&pPager->jfd);
drh8cfbf082001-09-19 13:22:39 +0000245 pPager->journalOpen = 0;
246 sqliteOsDelete(pPager->zJournal);
drha7fcb052001-12-14 15:09:55 +0000247 rc = sqliteOsReadLock(&pPager->fd);
248 assert( rc==SQLITE_OK );
drh6019e162001-07-02 17:51:45 +0000249 sqliteFree( pPager->aInJournal );
250 pPager->aInJournal = 0;
drhd9b02572001-04-15 00:37:09 +0000251 for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
252 pPg->inJournal = 0;
253 pPg->dirty = 0;
254 }
drha7fcb052001-12-14 15:09:55 +0000255 pPager->state = SQLITE_READLOCK;
drhed7c8552001-04-11 14:29:21 +0000256 return rc;
257}
258
drhed7c8552001-04-11 14:29:21 +0000259/*
drhfa86c412002-02-02 15:01:15 +0000260** Read a single page from the journal file opened on file descriptor
261** jfd. Playback this one page.
262*/
263static int pager_playback_one_page(Pager *pPager, OsFile *jfd){
264 int rc;
265 PgHdr *pPg; /* An existing page in the cache */
266 PageRecord pgRec;
267
drh663fc632002-02-02 18:49:19 +0000268 rc = sqliteOsRead(jfd, &pgRec, sizeof(pgRec));
drhfa86c412002-02-02 15:01:15 +0000269 if( rc!=SQLITE_OK ) return rc;
270
271 /* Sanity checking on the page */
272 if( pgRec.pgno>pPager->dbSize || pgRec.pgno==0 ) return SQLITE_CORRUPT;
273
274 /* Playback the page. Update the in-memory copy of the page
275 ** at the same time, if there is one.
276 */
277 pPg = pager_lookup(pPager, pgRec.pgno);
278 if( pPg ){
279 memcpy(PGHDR_TO_DATA(pPg), pgRec.aData, SQLITE_PAGE_SIZE);
280 memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
281 }
282 rc = sqliteOsSeek(&pPager->fd, (pgRec.pgno-1)*SQLITE_PAGE_SIZE);
283 if( rc==SQLITE_OK ){
284 rc = sqliteOsWrite(&pPager->fd, pgRec.aData, SQLITE_PAGE_SIZE);
285 }
286 return rc;
287}
288
289/*
drhed7c8552001-04-11 14:29:21 +0000290** Playback the journal and thus restore the database file to
291** the state it was in before we started making changes.
292**
drhd9b02572001-04-15 00:37:09 +0000293** The journal file format is as follows: There is an initial
294** file-type string for sanity checking. Then there is a single
295** Pgno number which is the number of pages in the database before
296** changes were made. The database is truncated to this size.
drh306dc212001-05-21 13:45:10 +0000297** Next come zero or more page records where each page record
298** consists of a Pgno and SQLITE_PAGE_SIZE bytes of data. See
299** the PageRecord structure for details.
drhed7c8552001-04-11 14:29:21 +0000300**
drhd9b02572001-04-15 00:37:09 +0000301** If the file opened as the journal file is not a well-formed
302** journal file (as determined by looking at the magic number
303** at the beginning) then this routine returns SQLITE_PROTOCOL.
304** If any other errors occur during playback, the database will
305** likely be corrupted, so the PAGER_ERR_CORRUPT bit is set in
306** pPager->errMask and SQLITE_CORRUPT is returned. If it all
307** works, then this routine returns SQLITE_OK.
drhed7c8552001-04-11 14:29:21 +0000308*/
drhd9b02572001-04-15 00:37:09 +0000309static int pager_playback(Pager *pPager){
310 int nRec; /* Number of Records */
311 int i; /* Loop counter */
312 Pgno mxPg = 0; /* Size of the original file in pages */
drhd9b02572001-04-15 00:37:09 +0000313 unsigned char aMagic[sizeof(aJournalMagic)];
drhed7c8552001-04-11 14:29:21 +0000314 int rc;
315
drhc3a64ba2001-11-22 00:01:27 +0000316 /* Figure out how many records are in the journal. Abort early if
317 ** the journal is empty.
drhed7c8552001-04-11 14:29:21 +0000318 */
drh8cfbf082001-09-19 13:22:39 +0000319 assert( pPager->journalOpen );
drha7fcb052001-12-14 15:09:55 +0000320 sqliteOsSeek(&pPager->jfd, 0);
321 rc = sqliteOsFileSize(&pPager->jfd, &nRec);
drhc3a64ba2001-11-22 00:01:27 +0000322 if( rc!=SQLITE_OK ){
323 goto end_playback;
324 }
325 nRec = (nRec - (sizeof(aMagic)+sizeof(Pgno))) / sizeof(PageRecord);
326 if( nRec<=0 ){
327 goto end_playback;
328 }
329
330 /* Read the beginning of the journal and truncate the
331 ** database file back to its original size.
332 */
drha7fcb052001-12-14 15:09:55 +0000333 rc = sqliteOsRead(&pPager->jfd, aMagic, sizeof(aMagic));
drhd9b02572001-04-15 00:37:09 +0000334 if( rc!=SQLITE_OK || memcmp(aMagic,aJournalMagic,sizeof(aMagic))!=0 ){
drh81a20f22001-10-12 17:30:04 +0000335 rc = SQLITE_PROTOCOL;
336 goto end_playback;
drhd9b02572001-04-15 00:37:09 +0000337 }
drha7fcb052001-12-14 15:09:55 +0000338 rc = sqliteOsRead(&pPager->jfd, &mxPg, sizeof(mxPg));
drhd9b02572001-04-15 00:37:09 +0000339 if( rc!=SQLITE_OK ){
drh81a20f22001-10-12 17:30:04 +0000340 goto end_playback;
drhd9b02572001-04-15 00:37:09 +0000341 }
drha7fcb052001-12-14 15:09:55 +0000342 rc = sqliteOsTruncate(&pPager->fd, mxPg*SQLITE_PAGE_SIZE);
drh81a20f22001-10-12 17:30:04 +0000343 if( rc!=SQLITE_OK ){
344 goto end_playback;
345 }
drhd9b02572001-04-15 00:37:09 +0000346 pPager->dbSize = mxPg;
347
drhfa86c412002-02-02 15:01:15 +0000348 /* Copy original pages out of the journal and back into the database file.
drhed7c8552001-04-11 14:29:21 +0000349 */
drhd9b02572001-04-15 00:37:09 +0000350 for(i=nRec-1; i>=0; i--){
drhfa86c412002-02-02 15:01:15 +0000351 rc = pager_playback_one_page(pPager, &pPager->jfd);
drhd9b02572001-04-15 00:37:09 +0000352 if( rc!=SQLITE_OK ) break;
drhed7c8552001-04-11 14:29:21 +0000353 }
drh81a20f22001-10-12 17:30:04 +0000354
355end_playback:
drhd9b02572001-04-15 00:37:09 +0000356 if( rc!=SQLITE_OK ){
357 pager_unwritelock(pPager);
358 pPager->errMask |= PAGER_ERR_CORRUPT;
359 rc = SQLITE_CORRUPT;
360 }else{
361 rc = pager_unwritelock(pPager);
drhed7c8552001-04-11 14:29:21 +0000362 }
drhd9b02572001-04-15 00:37:09 +0000363 return rc;
drhed7c8552001-04-11 14:29:21 +0000364}
365
366/*
drhfa86c412002-02-02 15:01:15 +0000367** Playback the checkpoint journal.
368**
369** This is similar to playing back the transaction journal but with
370** a few extra twists.
371**
drh663fc632002-02-02 18:49:19 +0000372** (1) The number of pages in the database file at the start of
373** the checkpoint is stored in pPager->ckptSize, not in the
374** journal file itself.
drhfa86c412002-02-02 15:01:15 +0000375**
376** (2) In addition to playing back the checkpoint journal, also
377** playback all pages of the transaction journal beginning
378** at offset pPager->ckptJSize.
379*/
380static int pager_ckpt_playback(Pager *pPager){
381 int nRec; /* Number of Records */
382 int i; /* Loop counter */
383 int rc;
384
385 /* Truncate the database back to its original size.
386 */
drh663fc632002-02-02 18:49:19 +0000387 rc = sqliteOsTruncate(&pPager->fd, pPager->ckptSize*SQLITE_PAGE_SIZE);
drhfa86c412002-02-02 15:01:15 +0000388 pPager->dbSize = pPager->ckptSize;
389
390 /* Figure out how many records are in the checkpoint journal.
391 */
392 assert( pPager->ckptOpen && pPager->journalOpen );
393 sqliteOsSeek(&pPager->cpfd, 0);
394 rc = sqliteOsFileSize(&pPager->cpfd, &nRec);
395 if( rc!=SQLITE_OK ){
396 goto end_ckpt_playback;
397 }
398 nRec /= sizeof(PageRecord);
399
400 /* Copy original pages out of the checkpoint journal and back into the
401 ** database file.
402 */
403 for(i=nRec-1; i>=0; i--){
404 rc = pager_playback_one_page(pPager, &pPager->cpfd);
405 if( rc!=SQLITE_OK ) goto end_ckpt_playback;
406 }
407
408 /* Figure out how many pages need to be copied out of the transaction
409 ** journal.
410 */
411 rc = sqliteOsSeek(&pPager->jfd, pPager->ckptJSize);
412 if( rc!=SQLITE_OK ){
413 goto end_ckpt_playback;
414 }
415 rc = sqliteOsFileSize(&pPager->jfd, &nRec);
416 if( rc!=SQLITE_OK ){
417 goto end_ckpt_playback;
418 }
419 nRec = (nRec - pPager->ckptJSize)/sizeof(PageRecord);
420 for(i=nRec-1; i>=0; i--){
421 rc = pager_playback_one_page(pPager, &pPager->jfd);
422 if( rc!=SQLITE_OK ) goto end_ckpt_playback;
423 }
424
425
426end_ckpt_playback:
drhfa86c412002-02-02 15:01:15 +0000427 if( rc!=SQLITE_OK ){
drhfa86c412002-02-02 15:01:15 +0000428 pPager->errMask |= PAGER_ERR_CORRUPT;
429 rc = SQLITE_CORRUPT;
drhfa86c412002-02-02 15:01:15 +0000430 }
431 return rc;
432}
433
434/*
drhf57b14a2001-09-14 18:54:08 +0000435** Change the maximum number of in-memory pages that are allowed.
436*/
437void sqlitepager_set_cachesize(Pager *pPager, int mxPage){
438 if( mxPage>10 ){
439 pPager->mxPage = mxPage;
440 }
441}
442
443/*
drhfa86c412002-02-02 15:01:15 +0000444** Open a temporary file. Write the name of the file into zName
445** (zName must be at least SQLITE_TEMPNAME_SIZE bytes long.) Write
446** the file descriptor into *fd. Return SQLITE_OK on success or some
447** other error code if we fail.
448**
449** The OS will automatically delete the temporary file when it is
450** closed.
451*/
452static int sqlitepager_opentemp(char *zFile, OsFile *fd){
453 int cnt = 8;
454 int rc;
455 do{
456 cnt--;
457 sqliteOsTempFileName(zFile);
458 rc = sqliteOsOpenExclusive(zFile, fd, 1);
459 }while( cnt>0 && rc!=SQLITE_OK );
460 return rc;
461}
462
463/*
drhed7c8552001-04-11 14:29:21 +0000464** Create a new page cache and put a pointer to the page cache in *ppPager.
drh5e00f6c2001-09-13 13:46:56 +0000465** The file to be cached need not exist. The file is not locked until
drhd9b02572001-04-15 00:37:09 +0000466** the first call to sqlitepager_get() and is only held open until the
467** last page is released using sqlitepager_unref().
drh382c0242001-10-06 16:33:02 +0000468**
drh6446c4d2001-12-15 14:22:18 +0000469** If zFilename is NULL then a randomly-named temporary file is created
470** and used as the file to be cached. The file will be deleted
471** automatically when it is closed.
drhed7c8552001-04-11 14:29:21 +0000472*/
drh7e3b0a02001-04-28 16:52:40 +0000473int sqlitepager_open(
474 Pager **ppPager, /* Return the Pager structure here */
475 const char *zFilename, /* Name of the database file to open */
476 int mxPage, /* Max number of in-memory cache pages */
477 int nExtra /* Extra bytes append to each in-memory page */
478){
drhed7c8552001-04-11 14:29:21 +0000479 Pager *pPager;
480 int nameLen;
drh8cfbf082001-09-19 13:22:39 +0000481 OsFile fd;
482 int rc;
drh5e00f6c2001-09-13 13:46:56 +0000483 int tempFile;
484 int readOnly = 0;
drh8cfbf082001-09-19 13:22:39 +0000485 char zTemp[SQLITE_TEMPNAME_SIZE];
drhed7c8552001-04-11 14:29:21 +0000486
drhd9b02572001-04-15 00:37:09 +0000487 *ppPager = 0;
488 if( sqlite_malloc_failed ){
489 return SQLITE_NOMEM;
490 }
drh5e00f6c2001-09-13 13:46:56 +0000491 if( zFilename ){
drh8cfbf082001-09-19 13:22:39 +0000492 rc = sqliteOsOpenReadWrite(zFilename, &fd, &readOnly);
drh5e00f6c2001-09-13 13:46:56 +0000493 tempFile = 0;
494 }else{
drhfa86c412002-02-02 15:01:15 +0000495 rc = sqlitepager_opentemp(zTemp, &fd);
drh5e00f6c2001-09-13 13:46:56 +0000496 zFilename = zTemp;
497 tempFile = 1;
498 }
drh8cfbf082001-09-19 13:22:39 +0000499 if( rc!=SQLITE_OK ){
drhed7c8552001-04-11 14:29:21 +0000500 return SQLITE_CANTOPEN;
501 }
502 nameLen = strlen(zFilename);
503 pPager = sqliteMalloc( sizeof(*pPager) + nameLen*2 + 30 );
drhd9b02572001-04-15 00:37:09 +0000504 if( pPager==0 ){
drha7fcb052001-12-14 15:09:55 +0000505 sqliteOsClose(&fd);
drhd9b02572001-04-15 00:37:09 +0000506 return SQLITE_NOMEM;
507 }
drhed7c8552001-04-11 14:29:21 +0000508 pPager->zFilename = (char*)&pPager[1];
509 pPager->zJournal = &pPager->zFilename[nameLen+1];
510 strcpy(pPager->zFilename, zFilename);
511 strcpy(pPager->zJournal, zFilename);
512 strcpy(&pPager->zJournal[nameLen], "-journal");
513 pPager->fd = fd;
drh8cfbf082001-09-19 13:22:39 +0000514 pPager->journalOpen = 0;
drhfa86c412002-02-02 15:01:15 +0000515 pPager->ckptOpen = 0;
drhed7c8552001-04-11 14:29:21 +0000516 pPager->nRef = 0;
517 pPager->dbSize = -1;
drhfa86c412002-02-02 15:01:15 +0000518 pPager->ckptSize = 0;
519 pPager->ckptJSize = 0;
drhed7c8552001-04-11 14:29:21 +0000520 pPager->nPage = 0;
drhd79caeb2001-04-15 02:27:24 +0000521 pPager->mxPage = mxPage>5 ? mxPage : 10;
drhed7c8552001-04-11 14:29:21 +0000522 pPager->state = SQLITE_UNLOCK;
drhd9b02572001-04-15 00:37:09 +0000523 pPager->errMask = 0;
drh5e00f6c2001-09-13 13:46:56 +0000524 pPager->tempFile = tempFile;
525 pPager->readOnly = readOnly;
drhf57b14a2001-09-14 18:54:08 +0000526 pPager->needSync = 0;
drhed7c8552001-04-11 14:29:21 +0000527 pPager->pFirst = 0;
528 pPager->pLast = 0;
drh7c717f72001-06-24 20:39:41 +0000529 pPager->nExtra = nExtra;
drhed7c8552001-04-11 14:29:21 +0000530 memset(pPager->aHash, 0, sizeof(pPager->aHash));
531 *ppPager = pPager;
532 return SQLITE_OK;
533}
534
535/*
drh72f82862001-05-24 21:06:34 +0000536** Set the destructor for this pager. If not NULL, the destructor is called
drh5e00f6c2001-09-13 13:46:56 +0000537** when the reference count on each page reaches zero. The destructor can
538** be used to clean up information in the extra segment appended to each page.
drh72f82862001-05-24 21:06:34 +0000539**
540** The destructor is not called as a result sqlitepager_close().
541** Destructors are only called by sqlitepager_unref().
542*/
543void sqlitepager_set_destructor(Pager *pPager, void (*xDesc)(void*)){
544 pPager->xDestructor = xDesc;
545}
546
547/*
drh5e00f6c2001-09-13 13:46:56 +0000548** Return the total number of pages in the disk file associated with
549** pPager.
drhed7c8552001-04-11 14:29:21 +0000550*/
drhd9b02572001-04-15 00:37:09 +0000551int sqlitepager_pagecount(Pager *pPager){
drhed7c8552001-04-11 14:29:21 +0000552 int n;
drhd9b02572001-04-15 00:37:09 +0000553 assert( pPager!=0 );
drhed7c8552001-04-11 14:29:21 +0000554 if( pPager->dbSize>=0 ){
555 return pPager->dbSize;
556 }
drha7fcb052001-12-14 15:09:55 +0000557 if( sqliteOsFileSize(&pPager->fd, &n)!=SQLITE_OK ){
drh81a20f22001-10-12 17:30:04 +0000558 pPager->errMask |= PAGER_ERR_DISK;
drh8cfbf082001-09-19 13:22:39 +0000559 return 0;
drhed7c8552001-04-11 14:29:21 +0000560 }
drh8cfbf082001-09-19 13:22:39 +0000561 n /= SQLITE_PAGE_SIZE;
drhd9b02572001-04-15 00:37:09 +0000562 if( pPager->state!=SQLITE_UNLOCK ){
drhed7c8552001-04-11 14:29:21 +0000563 pPager->dbSize = n;
564 }
565 return n;
566}
567
568/*
569** Shutdown the page cache. Free all memory and close all files.
570**
571** If a transaction was in progress when this routine is called, that
572** transaction is rolled back. All outstanding pages are invalidated
573** and their memory is freed. Any attempt to use a page associated
574** with this page cache after this function returns will likely
575** result in a coredump.
576*/
drhd9b02572001-04-15 00:37:09 +0000577int sqlitepager_close(Pager *pPager){
578 PgHdr *pPg, *pNext;
drhed7c8552001-04-11 14:29:21 +0000579 switch( pPager->state ){
580 case SQLITE_WRITELOCK: {
drhd9b02572001-04-15 00:37:09 +0000581 sqlitepager_rollback(pPager);
drha7fcb052001-12-14 15:09:55 +0000582 sqliteOsUnlock(&pPager->fd);
drh8cfbf082001-09-19 13:22:39 +0000583 assert( pPager->journalOpen==0 );
drhed7c8552001-04-11 14:29:21 +0000584 break;
585 }
586 case SQLITE_READLOCK: {
drha7fcb052001-12-14 15:09:55 +0000587 sqliteOsUnlock(&pPager->fd);
drhed7c8552001-04-11 14:29:21 +0000588 break;
589 }
590 default: {
591 /* Do nothing */
592 break;
593 }
594 }
drhd9b02572001-04-15 00:37:09 +0000595 for(pPg=pPager->pAll; pPg; pPg=pNext){
596 pNext = pPg->pNextAll;
597 sqliteFree(pPg);
drhed7c8552001-04-11 14:29:21 +0000598 }
drha7fcb052001-12-14 15:09:55 +0000599 sqliteOsClose(&pPager->fd);
drh8cfbf082001-09-19 13:22:39 +0000600 assert( pPager->journalOpen==0 );
drh5e00f6c2001-09-13 13:46:56 +0000601 if( pPager->tempFile ){
drhfa86c412002-02-02 15:01:15 +0000602 /* sqliteOsDelete(pPager->zFilename); */
drh5e00f6c2001-09-13 13:46:56 +0000603 }
drhed7c8552001-04-11 14:29:21 +0000604 sqliteFree(pPager);
605 return SQLITE_OK;
606}
607
608/*
drh5e00f6c2001-09-13 13:46:56 +0000609** Return the page number for the given page data.
drhed7c8552001-04-11 14:29:21 +0000610*/
drhd9b02572001-04-15 00:37:09 +0000611Pgno sqlitepager_pagenumber(void *pData){
drhed7c8552001-04-11 14:29:21 +0000612 PgHdr *p = DATA_TO_PGHDR(pData);
613 return p->pgno;
614}
615
616/*
drh7e3b0a02001-04-28 16:52:40 +0000617** Increment the reference count for a page. If the page is
618** currently on the freelist (the reference count is zero) then
619** remove it from the freelist.
620*/
drhdf0b3b02001-06-23 11:36:20 +0000621static void page_ref(PgHdr *pPg){
drh7e3b0a02001-04-28 16:52:40 +0000622 if( pPg->nRef==0 ){
623 /* The page is currently on the freelist. Remove it. */
624 if( pPg->pPrevFree ){
625 pPg->pPrevFree->pNextFree = pPg->pNextFree;
626 }else{
627 pPg->pPager->pFirst = pPg->pNextFree;
628 }
629 if( pPg->pNextFree ){
630 pPg->pNextFree->pPrevFree = pPg->pPrevFree;
631 }else{
632 pPg->pPager->pLast = pPg->pPrevFree;
633 }
634 pPg->pPager->nRef++;
635 }
636 pPg->nRef++;
drhdd793422001-06-28 01:54:48 +0000637 REFINFO(pPg);
drhdf0b3b02001-06-23 11:36:20 +0000638}
639
640/*
641** Increment the reference count for a page. The input pointer is
642** a reference to the page data.
643*/
644int sqlitepager_ref(void *pData){
645 PgHdr *pPg = DATA_TO_PGHDR(pData);
646 page_ref(pPg);
drh8c42ca92001-06-22 19:15:00 +0000647 return SQLITE_OK;
drh7e3b0a02001-04-28 16:52:40 +0000648}
649
650/*
drhb19a2bc2001-09-16 00:13:26 +0000651** Sync the journal and then write all free dirty pages to the database
652** file.
653**
654** Writing all free dirty pages to the database after the sync is a
655** non-obvious optimization. fsync() is an expensive operation so we
drh6446c4d2001-12-15 14:22:18 +0000656** want to minimize the number it is called. After an fsync() call,
657** we are free to write dirty pages back to the database. It is best
658** to go ahead and write as many dirty pages as possible to minimize
659** the risk of having to do another fsync() later on. Writing dirty
660** free pages in this way was observed to make database operations go
661** up to 10 times faster.
drhfa86c412002-02-02 15:01:15 +0000662**
663** If we are writing to temporary database, there is no need to preserve
664** the integrity of the journal file, so we can save time and skip the
665** fsync().
drh50e5dad2001-09-15 00:57:28 +0000666*/
667static int syncAllPages(Pager *pPager){
668 PgHdr *pPg;
669 int rc = SQLITE_OK;
670 if( pPager->needSync ){
drhfa86c412002-02-02 15:01:15 +0000671 if( !pPager->tempFile ){
672 rc = sqliteOsSync(&pPager->jfd);
673 if( rc!=0 ) return rc;
674 }
drh50e5dad2001-09-15 00:57:28 +0000675 pPager->needSync = 0;
676 }
677 for(pPg=pPager->pFirst; pPg; pPg=pPg->pNextFree){
678 if( pPg->dirty ){
drha7fcb052001-12-14 15:09:55 +0000679 sqliteOsSeek(&pPager->fd, (pPg->pgno-1)*SQLITE_PAGE_SIZE);
680 rc = sqliteOsWrite(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
drh50e5dad2001-09-15 00:57:28 +0000681 if( rc!=SQLITE_OK ) break;
682 pPg->dirty = 0;
683 }
684 }
drh81a20f22001-10-12 17:30:04 +0000685 return rc;
drh50e5dad2001-09-15 00:57:28 +0000686}
687
688/*
drhd9b02572001-04-15 00:37:09 +0000689** Acquire a page.
690**
drh58a11682001-11-10 13:51:08 +0000691** A read lock on the disk file is obtained when the first page is acquired.
drh5e00f6c2001-09-13 13:46:56 +0000692** This read lock is dropped when the last page is released.
drhd9b02572001-04-15 00:37:09 +0000693**
drh306dc212001-05-21 13:45:10 +0000694** A _get works for any page number greater than 0. If the database
695** file is smaller than the requested page, then no actual disk
696** read occurs and the memory image of the page is initialized to
697** all zeros. The extra data appended to a page is always initialized
698** to zeros the first time a page is loaded into memory.
699**
drhd9b02572001-04-15 00:37:09 +0000700** The acquisition might fail for several reasons. In all cases,
701** an appropriate error code is returned and *ppPage is set to NULL.
drh7e3b0a02001-04-28 16:52:40 +0000702**
703** See also sqlitepager_lookup(). Both this routine and _lookup() attempt
704** to find a page in the in-memory cache first. If the page is not already
drh5e00f6c2001-09-13 13:46:56 +0000705** in memory, this routine goes to disk to read it in whereas _lookup()
drh7e3b0a02001-04-28 16:52:40 +0000706** just returns 0. This routine acquires a read-lock the first time it
707** has to go to disk, and could also playback an old journal if necessary.
708** Since _lookup() never goes to disk, it never has to deal with locks
709** or journal files.
drhed7c8552001-04-11 14:29:21 +0000710*/
drhd9b02572001-04-15 00:37:09 +0000711int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
drhed7c8552001-04-11 14:29:21 +0000712 PgHdr *pPg;
713
drhd9b02572001-04-15 00:37:09 +0000714 /* Make sure we have not hit any critical errors.
715 */
716 if( pPager==0 || pgno==0 ){
717 return SQLITE_ERROR;
718 }
719 if( pPager->errMask & ~(PAGER_ERR_FULL) ){
720 return pager_errcode(pPager);
721 }
722
drhed7c8552001-04-11 14:29:21 +0000723 /* If this is the first page accessed, then get a read lock
724 ** on the database file.
725 */
726 if( pPager->nRef==0 ){
drha7fcb052001-12-14 15:09:55 +0000727 if( sqliteOsReadLock(&pPager->fd)!=SQLITE_OK ){
drhed7c8552001-04-11 14:29:21 +0000728 *ppPage = 0;
729 return SQLITE_BUSY;
730 }
drhd9b02572001-04-15 00:37:09 +0000731 pPager->state = SQLITE_READLOCK;
drhed7c8552001-04-11 14:29:21 +0000732
733 /* If a journal file exists, try to play it back.
734 */
drh8cfbf082001-09-19 13:22:39 +0000735 if( sqliteOsFileExists(pPager->zJournal) ){
drhf57b3392001-10-08 13:22:32 +0000736 int rc, dummy;
drhed7c8552001-04-11 14:29:21 +0000737
drha7fcb052001-12-14 15:09:55 +0000738 /* Get a write lock on the database
739 */
740 rc = sqliteOsWriteLock(&pPager->fd);
741 if( rc!=SQLITE_OK ){
drh6446c4d2001-12-15 14:22:18 +0000742 rc = sqliteOsUnlock(&pPager->fd);
drha7fcb052001-12-14 15:09:55 +0000743 assert( rc==SQLITE_OK );
744 *ppPage = 0;
745 return SQLITE_BUSY;
746 }
747 pPager->state = SQLITE_WRITELOCK;
748
drhed7c8552001-04-11 14:29:21 +0000749 /* Open the journal for exclusive access. Return SQLITE_BUSY if
drhf57b3392001-10-08 13:22:32 +0000750 ** we cannot get exclusive access to the journal file.
751 **
752 ** Even though we will only be reading from the journal, not writing,
753 ** we have to open the journal for writing in order to obtain an
754 ** exclusive access lock.
drhed7c8552001-04-11 14:29:21 +0000755 */
drhf57b3392001-10-08 13:22:32 +0000756 rc = sqliteOsOpenReadWrite(pPager->zJournal, &pPager->jfd, &dummy);
drha7fcb052001-12-14 15:09:55 +0000757 if( rc!=SQLITE_OK ){
758 rc = sqliteOsUnlock(&pPager->fd);
759 assert( rc==SQLITE_OK );
drhed7c8552001-04-11 14:29:21 +0000760 *ppPage = 0;
761 return SQLITE_BUSY;
762 }
drha7fcb052001-12-14 15:09:55 +0000763 pPager->journalOpen = 1;
drhed7c8552001-04-11 14:29:21 +0000764
765 /* Playback and delete the journal. Drop the database write
766 ** lock and reacquire the read lock.
767 */
drhd9b02572001-04-15 00:37:09 +0000768 rc = pager_playback(pPager);
769 if( rc!=SQLITE_OK ){
770 return rc;
771 }
drhed7c8552001-04-11 14:29:21 +0000772 }
773 pPg = 0;
774 }else{
775 /* Search for page in cache */
drhd9b02572001-04-15 00:37:09 +0000776 pPg = pager_lookup(pPager, pgno);
drhed7c8552001-04-11 14:29:21 +0000777 }
778 if( pPg==0 ){
drhd9b02572001-04-15 00:37:09 +0000779 /* The requested page is not in the page cache. */
drhed7c8552001-04-11 14:29:21 +0000780 int h;
drh7e3b0a02001-04-28 16:52:40 +0000781 pPager->nMiss++;
drhed7c8552001-04-11 14:29:21 +0000782 if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 ){
783 /* Create a new page */
drh7e3b0a02001-04-28 16:52:40 +0000784 pPg = sqliteMalloc( sizeof(*pPg) + SQLITE_PAGE_SIZE + pPager->nExtra );
drhd9b02572001-04-15 00:37:09 +0000785 if( pPg==0 ){
786 *ppPage = 0;
787 pager_unwritelock(pPager);
788 pPager->errMask |= PAGER_ERR_MEM;
789 return SQLITE_NOMEM;
790 }
drhed7c8552001-04-11 14:29:21 +0000791 pPg->pPager = pPager;
drhd9b02572001-04-15 00:37:09 +0000792 pPg->pNextAll = pPager->pAll;
793 if( pPager->pAll ){
794 pPager->pAll->pPrevAll = pPg;
795 }
796 pPg->pPrevAll = 0;
drhd79caeb2001-04-15 02:27:24 +0000797 pPager->pAll = pPg;
drhd9b02572001-04-15 00:37:09 +0000798 pPager->nPage++;
drhed7c8552001-04-11 14:29:21 +0000799 }else{
drhd9b02572001-04-15 00:37:09 +0000800 /* Recycle an older page. First locate the page to be recycled.
801 ** Try to find one that is not dirty and is near the head of
802 ** of the free list */
drh50e5dad2001-09-15 00:57:28 +0000803 int cnt = pPager->mxPage/2;
drhed7c8552001-04-11 14:29:21 +0000804 pPg = pPager->pFirst;
drh6019e162001-07-02 17:51:45 +0000805 while( pPg->dirty && 0<cnt-- && pPg->pNextFree ){
drhd9b02572001-04-15 00:37:09 +0000806 pPg = pPg->pNextFree;
807 }
drhb19a2bc2001-09-16 00:13:26 +0000808
809 /* If we could not find a page that has not been used recently
810 ** and which is not dirty, then sync the journal and write all
811 ** dirty free pages into the database file, thus making them
812 ** clean pages and available for recycling.
813 **
814 ** We have to sync the journal before writing a page to the main
815 ** database. But syncing is a very slow operation. So after a
816 ** sync, it is best to write everything we can back to the main
817 ** database to minimize the risk of having to sync again in the
818 ** near future. That is way we write all dirty pages after a
819 ** sync.
820 */
drh50e5dad2001-09-15 00:57:28 +0000821 if( pPg==0 || pPg->dirty ){
822 int rc = syncAllPages(pPager);
823 if( rc!=0 ){
824 sqlitepager_rollback(pPager);
825 *ppPage = 0;
826 return SQLITE_IOERR;
827 }
828 pPg = pPager->pFirst;
829 }
drhd9b02572001-04-15 00:37:09 +0000830 assert( pPg->nRef==0 );
drh50e5dad2001-09-15 00:57:28 +0000831 assert( pPg->dirty==0 );
drhd9b02572001-04-15 00:37:09 +0000832
833 /* Unlink the old page from the free list and the hash table
834 */
drh6019e162001-07-02 17:51:45 +0000835 if( pPg->pPrevFree ){
836 pPg->pPrevFree->pNextFree = pPg->pNextFree;
drhed7c8552001-04-11 14:29:21 +0000837 }else{
drh6019e162001-07-02 17:51:45 +0000838 assert( pPager->pFirst==pPg );
839 pPager->pFirst = pPg->pNextFree;
drhed7c8552001-04-11 14:29:21 +0000840 }
drh6019e162001-07-02 17:51:45 +0000841 if( pPg->pNextFree ){
842 pPg->pNextFree->pPrevFree = pPg->pPrevFree;
843 }else{
844 assert( pPager->pLast==pPg );
845 pPager->pLast = pPg->pPrevFree;
846 }
847 pPg->pNextFree = pPg->pPrevFree = 0;
drhed7c8552001-04-11 14:29:21 +0000848 if( pPg->pNextHash ){
849 pPg->pNextHash->pPrevHash = pPg->pPrevHash;
850 }
851 if( pPg->pPrevHash ){
852 pPg->pPrevHash->pNextHash = pPg->pNextHash;
853 }else{
drhd9b02572001-04-15 00:37:09 +0000854 h = pager_hash(pPg->pgno);
drhed7c8552001-04-11 14:29:21 +0000855 assert( pPager->aHash[h]==pPg );
856 pPager->aHash[h] = pPg->pNextHash;
857 }
drh6019e162001-07-02 17:51:45 +0000858 pPg->pNextHash = pPg->pPrevHash = 0;
drhd9b02572001-04-15 00:37:09 +0000859 pPager->nOvfl++;
drhed7c8552001-04-11 14:29:21 +0000860 }
861 pPg->pgno = pgno;
drh1ab43002002-01-14 09:28:19 +0000862 if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
drh6019e162001-07-02 17:51:45 +0000863 pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0;
864 }else{
865 pPg->inJournal = 0;
866 }
drh663fc632002-02-02 18:49:19 +0000867 if( pPager->aInCkpt && (int)pgno<=pPager->ckptSize ){
drhfa86c412002-02-02 15:01:15 +0000868 pPg->inCkpt = (pPager->aInCkpt[pgno/8] & (1<<(pgno&7)))!=0;
869 }else{
870 pPg->inCkpt = 0;
871 }
drhed7c8552001-04-11 14:29:21 +0000872 pPg->dirty = 0;
873 pPg->nRef = 1;
drhdd793422001-06-28 01:54:48 +0000874 REFINFO(pPg);
drhd9b02572001-04-15 00:37:09 +0000875 pPager->nRef++;
876 h = pager_hash(pgno);
drhed7c8552001-04-11 14:29:21 +0000877 pPg->pNextHash = pPager->aHash[h];
878 pPager->aHash[h] = pPg;
879 if( pPg->pNextHash ){
880 assert( pPg->pNextHash->pPrevHash==0 );
881 pPg->pNextHash->pPrevHash = pPg;
882 }
drh306dc212001-05-21 13:45:10 +0000883 if( pPager->dbSize<0 ) sqlitepager_pagecount(pPager);
drh1ab43002002-01-14 09:28:19 +0000884 if( pPager->dbSize<(int)pgno ){
drh306dc212001-05-21 13:45:10 +0000885 memset(PGHDR_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);
886 }else{
drh81a20f22001-10-12 17:30:04 +0000887 int rc;
drha7fcb052001-12-14 15:09:55 +0000888 sqliteOsSeek(&pPager->fd, (pgno-1)*SQLITE_PAGE_SIZE);
889 rc = sqliteOsRead(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
drh81a20f22001-10-12 17:30:04 +0000890 if( rc!=SQLITE_OK ){
891 return rc;
892 }
drh306dc212001-05-21 13:45:10 +0000893 }
drh7e3b0a02001-04-28 16:52:40 +0000894 if( pPager->nExtra>0 ){
895 memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
896 }
drhed7c8552001-04-11 14:29:21 +0000897 }else{
drhd9b02572001-04-15 00:37:09 +0000898 /* The requested page is in the page cache. */
drh7e3b0a02001-04-28 16:52:40 +0000899 pPager->nHit++;
drhdf0b3b02001-06-23 11:36:20 +0000900 page_ref(pPg);
drhed7c8552001-04-11 14:29:21 +0000901 }
902 *ppPage = PGHDR_TO_DATA(pPg);
903 return SQLITE_OK;
904}
905
906/*
drh7e3b0a02001-04-28 16:52:40 +0000907** Acquire a page if it is already in the in-memory cache. Do
908** not read the page from disk. Return a pointer to the page,
909** or 0 if the page is not in cache.
910**
911** See also sqlitepager_get(). The difference between this routine
912** and sqlitepager_get() is that _get() will go to the disk and read
913** in the page if the page is not already in cache. This routine
drh5e00f6c2001-09-13 13:46:56 +0000914** returns NULL if the page is not in cache or if a disk I/O error
915** has ever happened.
drh7e3b0a02001-04-28 16:52:40 +0000916*/
917void *sqlitepager_lookup(Pager *pPager, Pgno pgno){
918 PgHdr *pPg;
919
920 /* Make sure we have not hit any critical errors.
921 */
922 if( pPager==0 || pgno==0 ){
923 return 0;
924 }
925 if( pPager->errMask & ~(PAGER_ERR_FULL) ){
926 return 0;
927 }
928 if( pPager->nRef==0 ){
929 return 0;
930 }
931 pPg = pager_lookup(pPager, pgno);
932 if( pPg==0 ) return 0;
drhdf0b3b02001-06-23 11:36:20 +0000933 page_ref(pPg);
drh7e3b0a02001-04-28 16:52:40 +0000934 return PGHDR_TO_DATA(pPg);
935}
936
937/*
drhed7c8552001-04-11 14:29:21 +0000938** Release a page.
939**
940** If the number of references to the page drop to zero, then the
941** page is added to the LRU list. When all references to all pages
drhd9b02572001-04-15 00:37:09 +0000942** are released, a rollback occurs and the lock on the database is
drhed7c8552001-04-11 14:29:21 +0000943** removed.
944*/
drhd9b02572001-04-15 00:37:09 +0000945int sqlitepager_unref(void *pData){
drhed7c8552001-04-11 14:29:21 +0000946 PgHdr *pPg;
drhd9b02572001-04-15 00:37:09 +0000947
948 /* Decrement the reference count for this page
949 */
drhed7c8552001-04-11 14:29:21 +0000950 pPg = DATA_TO_PGHDR(pData);
951 assert( pPg->nRef>0 );
drhed7c8552001-04-11 14:29:21 +0000952 pPg->nRef--;
drhdd793422001-06-28 01:54:48 +0000953 REFINFO(pPg);
drhd9b02572001-04-15 00:37:09 +0000954
drh72f82862001-05-24 21:06:34 +0000955 /* When the number of references to a page reach 0, call the
956 ** destructor and add the page to the freelist.
drhd9b02572001-04-15 00:37:09 +0000957 */
drhed7c8552001-04-11 14:29:21 +0000958 if( pPg->nRef==0 ){
drh1eaa2692001-09-18 02:02:23 +0000959 Pager *pPager;
960 pPager = pPg->pPager;
drhd9b02572001-04-15 00:37:09 +0000961 pPg->pNextFree = 0;
962 pPg->pPrevFree = pPager->pLast;
drhed7c8552001-04-11 14:29:21 +0000963 pPager->pLast = pPg;
drhd9b02572001-04-15 00:37:09 +0000964 if( pPg->pPrevFree ){
965 pPg->pPrevFree->pNextFree = pPg;
drhed7c8552001-04-11 14:29:21 +0000966 }else{
967 pPager->pFirst = pPg;
968 }
drh72f82862001-05-24 21:06:34 +0000969 if( pPager->xDestructor ){
970 pPager->xDestructor(pData);
971 }
drhd9b02572001-04-15 00:37:09 +0000972
973 /* When all pages reach the freelist, drop the read lock from
974 ** the database file.
975 */
976 pPager->nRef--;
977 assert( pPager->nRef>=0 );
978 if( pPager->nRef==0 ){
979 pager_reset(pPager);
980 }
drhed7c8552001-04-11 14:29:21 +0000981 }
drhd9b02572001-04-15 00:37:09 +0000982 return SQLITE_OK;
drhed7c8552001-04-11 14:29:21 +0000983}
984
985/*
986** Mark a data page as writeable. The page is written into the journal
987** if it is not there already. This routine must be called before making
988** changes to a page.
989**
990** The first time this routine is called, the pager creates a new
991** journal and acquires a write lock on the database. If the write
992** lock could not be acquired, this routine returns SQLITE_BUSY. The
drh306dc212001-05-21 13:45:10 +0000993** calling routine must check for that return value and be careful not to
drhed7c8552001-04-11 14:29:21 +0000994** change any page data until this routine returns SQLITE_OK.
drhd9b02572001-04-15 00:37:09 +0000995**
996** If the journal file could not be written because the disk is full,
997** then this routine returns SQLITE_FULL and does an immediate rollback.
998** All subsequent write attempts also return SQLITE_FULL until there
999** is a call to sqlitepager_commit() or sqlitepager_rollback() to
1000** reset.
drhed7c8552001-04-11 14:29:21 +00001001*/
drhd9b02572001-04-15 00:37:09 +00001002int sqlitepager_write(void *pData){
drh69688d52001-04-14 16:38:23 +00001003 PgHdr *pPg = DATA_TO_PGHDR(pData);
1004 Pager *pPager = pPg->pPager;
drhd79caeb2001-04-15 02:27:24 +00001005 int rc = SQLITE_OK;
drh69688d52001-04-14 16:38:23 +00001006
drh6446c4d2001-12-15 14:22:18 +00001007 /* Check for errors
1008 */
drhd9b02572001-04-15 00:37:09 +00001009 if( pPager->errMask ){
1010 return pager_errcode(pPager);
1011 }
drh5e00f6c2001-09-13 13:46:56 +00001012 if( pPager->readOnly ){
1013 return SQLITE_PERM;
1014 }
drh6446c4d2001-12-15 14:22:18 +00001015
1016 /* Mark the page as dirty. If the page has already been written
1017 ** to the journal then we can return right away.
1018 */
drhd9b02572001-04-15 00:37:09 +00001019 pPg->dirty = 1;
drhfa86c412002-02-02 15:01:15 +00001020 if( pPg->inJournal && (pPg->inCkpt || pPager->ckptOpen==0) ){
1021 return SQLITE_OK;
1022 }
drh6446c4d2001-12-15 14:22:18 +00001023
1024 /* If we get this far, it means that the page needs to be
drhfa86c412002-02-02 15:01:15 +00001025 ** written to the transaction journal or the ckeckpoint journal
1026 ** or both.
1027 **
1028 ** First check to see that the transaction journal exists and
1029 ** create it if it does not.
drh6446c4d2001-12-15 14:22:18 +00001030 */
drhd9b02572001-04-15 00:37:09 +00001031 assert( pPager->state!=SQLITE_UNLOCK );
drhed7c8552001-04-11 14:29:21 +00001032 if( pPager->state==SQLITE_READLOCK ){
drh6019e162001-07-02 17:51:45 +00001033 assert( pPager->aInJournal==0 );
drha7fcb052001-12-14 15:09:55 +00001034 rc = sqliteOsWriteLock(&pPager->fd);
1035 if( rc!=SQLITE_OK ){
1036 return rc;
1037 }
drh6019e162001-07-02 17:51:45 +00001038 pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 );
1039 if( pPager->aInJournal==0 ){
drha7fcb052001-12-14 15:09:55 +00001040 sqliteOsReadLock(&pPager->fd);
drh6019e162001-07-02 17:51:45 +00001041 return SQLITE_NOMEM;
1042 }
drhfa86c412002-02-02 15:01:15 +00001043 rc = sqliteOsOpenExclusive(pPager->zJournal, &pPager->jfd, 0);
drh8cfbf082001-09-19 13:22:39 +00001044 if( rc!=SQLITE_OK ){
drh6d4abfb2001-10-22 02:58:08 +00001045 sqliteFree(pPager->aInJournal);
drha7fcb052001-12-14 15:09:55 +00001046 pPager->aInJournal = 0;
1047 sqliteOsReadLock(&pPager->fd);
drhed7c8552001-04-11 14:29:21 +00001048 return SQLITE_CANTOPEN;
1049 }
drh8cfbf082001-09-19 13:22:39 +00001050 pPager->journalOpen = 1;
drhf57b14a2001-09-14 18:54:08 +00001051 pPager->needSync = 0;
drhed7c8552001-04-11 14:29:21 +00001052 pPager->state = SQLITE_WRITELOCK;
drhd9b02572001-04-15 00:37:09 +00001053 sqlitepager_pagecount(pPager);
drh69688d52001-04-14 16:38:23 +00001054 pPager->origDbSize = pPager->dbSize;
drha7fcb052001-12-14 15:09:55 +00001055 rc = sqliteOsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic));
drhd9b02572001-04-15 00:37:09 +00001056 if( rc==SQLITE_OK ){
drha7fcb052001-12-14 15:09:55 +00001057 rc = sqliteOsWrite(&pPager->jfd, &pPager->dbSize, sizeof(Pgno));
drhd9b02572001-04-15 00:37:09 +00001058 }
1059 if( rc!=SQLITE_OK ){
1060 rc = pager_unwritelock(pPager);
1061 if( rc==SQLITE_OK ) rc = SQLITE_FULL;
1062 return rc;
1063 }
drhed7c8552001-04-11 14:29:21 +00001064 }
drhd9b02572001-04-15 00:37:09 +00001065 assert( pPager->state==SQLITE_WRITELOCK );
drh8cfbf082001-09-19 13:22:39 +00001066 assert( pPager->journalOpen );
drh6446c4d2001-12-15 14:22:18 +00001067
drhfa86c412002-02-02 15:01:15 +00001068 /* The transaction journal now exists and we have a write lock on the
1069 ** main database file. Write the current page to the transaction
1070 ** journal if it is not there already.
drh6446c4d2001-12-15 14:22:18 +00001071 */
drhfa86c412002-02-02 15:01:15 +00001072 if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
drha7fcb052001-12-14 15:09:55 +00001073 rc = sqliteOsWrite(&pPager->jfd, &pPg->pgno, sizeof(Pgno));
drhd9b02572001-04-15 00:37:09 +00001074 if( rc==SQLITE_OK ){
drha7fcb052001-12-14 15:09:55 +00001075 rc = sqliteOsWrite(&pPager->jfd, pData, SQLITE_PAGE_SIZE);
drhd9b02572001-04-15 00:37:09 +00001076 }
1077 if( rc!=SQLITE_OK ){
1078 sqlitepager_rollback(pPager);
1079 pPager->errMask |= PAGER_ERR_FULL;
1080 return rc;
1081 }
drh6019e162001-07-02 17:51:45 +00001082 assert( pPager->aInJournal!=0 );
1083 pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
drhf57b14a2001-09-14 18:54:08 +00001084 pPager->needSync = 1;
drhfa86c412002-02-02 15:01:15 +00001085 pPg->inJournal = 1;
1086 if( pPager->ckptOpen ){
1087 pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
1088 pPg->inCkpt = 1;
1089 }
drh69688d52001-04-14 16:38:23 +00001090 }
drh6446c4d2001-12-15 14:22:18 +00001091
drhfa86c412002-02-02 15:01:15 +00001092 /* If the checkpoint journal is open and the page is not in it,
1093 ** then write the current page to the checkpoint journal.
drh6446c4d2001-12-15 14:22:18 +00001094 */
drh663fc632002-02-02 18:49:19 +00001095 if( pPager->ckptOpen && !pPg->inCkpt && (int)pPg->pgno<=pPager->ckptSize ){
drhfa86c412002-02-02 15:01:15 +00001096 assert( pPg->inJournal );
1097 rc = sqliteOsWrite(&pPager->cpfd, &pPg->pgno, sizeof(Pgno));
1098 if( rc==SQLITE_OK ){
1099 rc = sqliteOsWrite(&pPager->cpfd, pData, SQLITE_PAGE_SIZE);
1100 }
1101 if( rc!=SQLITE_OK ){
1102 sqlitepager_rollback(pPager);
1103 pPager->errMask |= PAGER_ERR_FULL;
1104 return rc;
1105 }
1106 assert( pPager->aInCkpt!=0 );
1107 pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
1108 pPg->inCkpt = 1;
1109 }
1110
1111 /* Update the database size and return.
1112 */
drh1ab43002002-01-14 09:28:19 +00001113 if( pPager->dbSize<(int)pPg->pgno ){
drh306dc212001-05-21 13:45:10 +00001114 pPager->dbSize = pPg->pgno;
1115 }
drh69688d52001-04-14 16:38:23 +00001116 return rc;
drhed7c8552001-04-11 14:29:21 +00001117}
1118
1119/*
drhaacc5432002-01-06 17:07:40 +00001120** Return TRUE if the page given in the argument was previously passed
drh6019e162001-07-02 17:51:45 +00001121** to sqlitepager_write(). In other words, return TRUE if it is ok
1122** to change the content of the page.
1123*/
1124int sqlitepager_iswriteable(void *pData){
1125 PgHdr *pPg = DATA_TO_PGHDR(pData);
1126 return pPg->dirty;
1127}
1128
1129/*
drhed7c8552001-04-11 14:29:21 +00001130** Commit all changes to the database and release the write lock.
drhd9b02572001-04-15 00:37:09 +00001131**
1132** If the commit fails for any reason, a rollback attempt is made
1133** and an error code is returned. If the commit worked, SQLITE_OK
1134** is returned.
drhed7c8552001-04-11 14:29:21 +00001135*/
drhd9b02572001-04-15 00:37:09 +00001136int sqlitepager_commit(Pager *pPager){
drha1b351a2001-09-14 16:42:12 +00001137 int rc;
drhed7c8552001-04-11 14:29:21 +00001138 PgHdr *pPg;
drhd9b02572001-04-15 00:37:09 +00001139
1140 if( pPager->errMask==PAGER_ERR_FULL ){
1141 rc = sqlitepager_rollback(pPager);
1142 if( rc==SQLITE_OK ) rc = SQLITE_FULL;
1143 return rc;
1144 }
1145 if( pPager->errMask!=0 ){
1146 rc = pager_errcode(pPager);
1147 return rc;
1148 }
1149 if( pPager->state!=SQLITE_WRITELOCK ){
1150 return SQLITE_ERROR;
1151 }
drh8cfbf082001-09-19 13:22:39 +00001152 assert( pPager->journalOpen );
drha7fcb052001-12-14 15:09:55 +00001153 if( pPager->needSync && sqliteOsSync(&pPager->jfd)!=SQLITE_OK ){
drhd9b02572001-04-15 00:37:09 +00001154 goto commit_abort;
drhed7c8552001-04-11 14:29:21 +00001155 }
drha1b351a2001-09-14 16:42:12 +00001156 for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
1157 if( pPg->dirty==0 ) continue;
drha7fcb052001-12-14 15:09:55 +00001158 rc = sqliteOsSeek(&pPager->fd, (pPg->pgno-1)*SQLITE_PAGE_SIZE);
drha1b351a2001-09-14 16:42:12 +00001159 if( rc!=SQLITE_OK ) goto commit_abort;
drha7fcb052001-12-14 15:09:55 +00001160 rc = sqliteOsWrite(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
drha1b351a2001-09-14 16:42:12 +00001161 if( rc!=SQLITE_OK ) goto commit_abort;
drhed7c8552001-04-11 14:29:21 +00001162 }
drha7fcb052001-12-14 15:09:55 +00001163 if( sqliteOsSync(&pPager->fd)!=SQLITE_OK ) goto commit_abort;
drhd9b02572001-04-15 00:37:09 +00001164 rc = pager_unwritelock(pPager);
1165 pPager->dbSize = -1;
1166 return rc;
1167
1168 /* Jump here if anything goes wrong during the commit process.
1169 */
1170commit_abort:
1171 rc = sqlitepager_rollback(pPager);
1172 if( rc==SQLITE_OK ){
1173 rc = SQLITE_FULL;
drhed7c8552001-04-11 14:29:21 +00001174 }
drhed7c8552001-04-11 14:29:21 +00001175 return rc;
1176}
1177
1178/*
1179** Rollback all changes. The database falls back to read-only mode.
1180** All in-memory cache pages revert to their original data contents.
1181** The journal is deleted.
drhd9b02572001-04-15 00:37:09 +00001182**
1183** This routine cannot fail unless some other process is not following
1184** the correct locking protocol (SQLITE_PROTOCOL) or unless some other
1185** process is writing trash into the journal file (SQLITE_CORRUPT) or
1186** unless a prior malloc() failed (SQLITE_NOMEM). Appropriate error
1187** codes are returned for all these occasions. Otherwise,
1188** SQLITE_OK is returned.
drhed7c8552001-04-11 14:29:21 +00001189*/
drhd9b02572001-04-15 00:37:09 +00001190int sqlitepager_rollback(Pager *pPager){
drhed7c8552001-04-11 14:29:21 +00001191 int rc;
drhd9b02572001-04-15 00:37:09 +00001192 if( pPager->errMask!=0 && pPager->errMask!=PAGER_ERR_FULL ){
1193 return pager_errcode(pPager);
drhed7c8552001-04-11 14:29:21 +00001194 }
drhd9b02572001-04-15 00:37:09 +00001195 if( pPager->state!=SQLITE_WRITELOCK ){
1196 return SQLITE_OK;
1197 }
1198 rc = pager_playback(pPager);
1199 if( rc!=SQLITE_OK ){
1200 rc = SQLITE_CORRUPT;
1201 pPager->errMask |= PAGER_ERR_CORRUPT;
1202 }
1203 pPager->dbSize = -1;
drhed7c8552001-04-11 14:29:21 +00001204 return rc;
drh98808ba2001-10-18 12:34:46 +00001205}
drhd9b02572001-04-15 00:37:09 +00001206
1207/*
drh5e00f6c2001-09-13 13:46:56 +00001208** Return TRUE if the database file is opened read-only. Return FALSE
1209** if the database is (in theory) writable.
1210*/
1211int sqlitepager_isreadonly(Pager *pPager){
drhbe0072d2001-09-13 14:46:09 +00001212 return pPager->readOnly;
drh5e00f6c2001-09-13 13:46:56 +00001213}
1214
1215/*
drhd9b02572001-04-15 00:37:09 +00001216** This routine is used for testing and analysis only.
1217*/
1218int *sqlitepager_stats(Pager *pPager){
1219 static int a[9];
1220 a[0] = pPager->nRef;
1221 a[1] = pPager->nPage;
1222 a[2] = pPager->mxPage;
1223 a[3] = pPager->dbSize;
1224 a[4] = pPager->state;
1225 a[5] = pPager->errMask;
1226 a[6] = pPager->nHit;
1227 a[7] = pPager->nMiss;
1228 a[8] = pPager->nOvfl;
1229 return a;
1230}
drhdd793422001-06-28 01:54:48 +00001231
drhfa86c412002-02-02 15:01:15 +00001232/*
1233** Set the checkpoint.
1234**
1235** This routine should be called with the transaction journal already
1236** open. A new checkpoint journal is created that can be used to rollback
1237** changes of a single command within a larger transaction.
1238*/
1239int sqlitepager_ckpt_begin(Pager *pPager){
1240 int rc;
1241 char zTemp[SQLITE_TEMPNAME_SIZE];
1242 assert( pPager->journalOpen );
1243 assert( !pPager->ckptOpen );
1244 pPager->aInCkpt = sqliteMalloc( pPager->dbSize/8 + 1 );
1245 if( pPager->aInCkpt==0 ){
1246 sqliteOsReadLock(&pPager->fd);
1247 return SQLITE_NOMEM;
1248 }
1249 rc = sqliteOsFileSize(&pPager->jfd, &pPager->ckptJSize);
1250 if( rc ) goto ckpt_begin_failed;
drh663fc632002-02-02 18:49:19 +00001251 pPager->ckptSize = pPager->dbSize;
drhfa86c412002-02-02 15:01:15 +00001252 rc = sqlitepager_opentemp(zTemp, &pPager->cpfd);
1253 if( rc ) goto ckpt_begin_failed;
1254 pPager->ckptOpen = 1;
1255 return SQLITE_OK;
1256
1257ckpt_begin_failed:
1258 if( pPager->aInCkpt ){
1259 sqliteFree(pPager->aInCkpt);
1260 pPager->aInCkpt = 0;
1261 }
1262 return rc;
1263}
1264
1265/*
1266** Commit a checkpoint.
1267*/
1268int sqlitepager_ckpt_commit(Pager *pPager){
drh663fc632002-02-02 18:49:19 +00001269 if( pPager->ckptOpen ){
1270 PgHdr *pPg;
1271 sqliteOsClose(&pPager->cpfd);
1272 pPager->ckptOpen = 0;
1273 sqliteFree( pPager->aInCkpt );
1274 pPager->aInCkpt = 0;
1275 for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
1276 pPg->inCkpt = 0;
1277 }
1278 }
drhfa86c412002-02-02 15:01:15 +00001279 return SQLITE_OK;
1280}
1281
1282/*
1283** Rollback a checkpoint.
1284*/
1285int sqlitepager_ckpt_rollback(Pager *pPager){
1286 int rc;
drh663fc632002-02-02 18:49:19 +00001287 if( pPager->ckptOpen ){
1288 rc = pager_ckpt_playback(pPager);
1289 sqlitepager_ckpt_commit(pPager);
1290 }else{
1291 rc = SQLITE_OK;
1292 }
drhfa86c412002-02-02 15:01:15 +00001293 return rc;
1294}
1295
drhdd793422001-06-28 01:54:48 +00001296#if SQLITE_TEST
1297/*
1298** Print a listing of all referenced pages and their ref count.
1299*/
1300void sqlitepager_refdump(Pager *pPager){
1301 PgHdr *pPg;
1302 for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
1303 if( pPg->nRef<=0 ) continue;
1304 printf("PAGE %3d addr=0x%08x nRef=%d\n",
1305 pPg->pgno, (int)PGHDR_TO_DATA(pPg), pPg->nRef);
1306 }
1307}
1308#endif