Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add an optional codec to the pager layer. (CVS 1214) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
2f0c122cfb84dea58d112324a0bdd8b8 |
User & Date: | drh 2004-02-09 01:20:37.000 |
Context
2004-02-09
| ||
14:35 | Add test case for ticket #601. (CVS 1215) (check-in: 096312dacb user: drh tags: trunk) | |
01:20 | Add an optional codec to the pager layer. (CVS 1214) (check-in: 2f0c122cfb user: drh tags: trunk) | |
2004-02-08
| ||
18:10 | Version 2.8.12 (CVS 1213) (check-in: 1736d415d7 user: drh tags: trunk) | |
Changes
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.96 2004/02/09 01:20:37 drh Exp $ */ #include "os.h" /* Must be first to enable large file support */ #include "sqliteInt.h" #include "pager.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #define SET_PAGER(X) #define CLR_PAGER(X) #define TRACE1(X) #define TRACE2(X,Y) #define TRACE3(X,Y,Z) #endif /* ** The page cache as a whole is always in one of the following ** states: ** ** SQLITE_UNLOCK The page cache is not currently reading or ** writing the database file. There is no | > > > > > > > > > > > > > | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | #define SET_PAGER(X) #define CLR_PAGER(X) #define TRACE1(X) #define TRACE2(X,Y) #define TRACE3(X,Y,Z) #endif /* ** Number of extra bytes of data allocated at the end of each page and ** stored on disk but not used by the higher level btree layer. */ #ifndef SQLITE_PAGE_RESERVE #define SQLITE_PAGE_RESERVE 0 #endif /* ** The total number of bytes stored on disk for each page. */ #define SQLITE_BLOCK_SIZE (SQLITE_PAGE_SIZE+SQLITE_PAGE_RESERVE) /* ** The page cache as a whole is always in one of the following ** states: ** ** SQLITE_UNLOCK The page cache is not currently reading or ** writing the database file. There is no |
︙ | ︙ | |||
109 110 111 112 113 114 115 | PgHdr *pNextCkpt, *pPrevCkpt; /* List of pages in the checkpoint journal */ u8 inJournal; /* TRUE if has been written to journal */ u8 inCkpt; /* TRUE if written to the checkpoint journal */ u8 dirty; /* TRUE if we need to write back changes */ u8 needSync; /* Sync journal before writing this page */ u8 alwaysRollback; /* Disable dont_rollback() for this page */ PgHdr *pDirty; /* Dirty pages sorted by PgHdr.pgno */ | | | | 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | PgHdr *pNextCkpt, *pPrevCkpt; /* List of pages in the checkpoint journal */ u8 inJournal; /* TRUE if has been written to journal */ u8 inCkpt; /* TRUE if written to the checkpoint journal */ u8 dirty; /* TRUE if we need to write back changes */ u8 needSync; /* Sync journal before writing this page */ u8 alwaysRollback; /* Disable dont_rollback() for this page */ PgHdr *pDirty; /* Dirty pages sorted by PgHdr.pgno */ /* SQLITE_BLOCK_SIZE bytes of page data follow this header */ /* Pager.nExtra bytes of local data follow the page data */ }; /* ** Convert a pointer to a PgHdr into a pointer to its data ** and back again. */ #define PGHDR_TO_DATA(P) ((void*)(&(P)[1])) #define DATA_TO_PGHDR(D) (&((PgHdr*)(D))[-1]) #define PGHDR_TO_EXTRA(P) ((void*)&((char*)(&(P)[1]))[SQLITE_BLOCK_SIZE]) /* ** How big to make the hash table used for locating in-memory pages ** by page number. */ #define N_PG_HASH 2048 |
︙ | ︙ | |||
154 155 156 157 158 159 160 161 162 163 164 165 166 167 | int ckptNRec; /* Number of records in the checkpoint journal */ int nExtra; /* Add this many bytes to each in-memory page */ void (*xDestructor)(void*); /* Call this routine when freeing pages */ int nPage; /* Total number of in-memory pages */ int nRef; /* Number of in-memory pages with PgHdr.nRef>0 */ int mxPage; /* Maximum number of pages to hold in cache */ int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */ u8 journalOpen; /* True if journal file descriptors is valid */ u8 journalStarted; /* True if header of journal is synced */ u8 useJournal; /* Use a rollback journal on this file */ u8 ckptOpen; /* True if the checkpoint journal is open */ u8 ckptInUse; /* True we are in a checkpoint */ u8 ckptAutoopen; /* Open ckpt journal when main journal is opened*/ u8 noSync; /* Do not sync the journal if true */ | > > | 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | int ckptNRec; /* Number of records in the checkpoint journal */ int nExtra; /* Add this many bytes to each in-memory page */ void (*xDestructor)(void*); /* Call this routine when freeing pages */ int nPage; /* Total number of in-memory pages */ int nRef; /* Number of in-memory pages with PgHdr.nRef>0 */ int mxPage; /* Maximum number of pages to hold in cache */ int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */ void (*xCodec)(void*,void*,int); /* Routine for en/decoding on-disk data */ void *pCodecArg; /* First argument to xCodec() */ u8 journalOpen; /* True if journal file descriptors is valid */ u8 journalStarted; /* True if header of journal is synced */ u8 useJournal; /* Use a rollback journal on this file */ u8 ckptOpen; /* True if the checkpoint journal is open */ u8 ckptInUse; /* True we are in a checkpoint */ u8 ckptAutoopen; /* Open ckpt journal when main journal is opened*/ u8 noSync; /* Do not sync the journal if true */ |
︙ | ︙ | |||
197 198 199 200 201 202 203 | ** ** Actually, this structure is the complete page record for pager ** formats less than 3. Beginning with format 3, this record is surrounded ** by two checksums. */ typedef struct PageRecord PageRecord; struct PageRecord { | | | | 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | ** ** Actually, this structure is the complete page record for pager ** formats less than 3. Beginning with format 3, this record is surrounded ** by two checksums. */ typedef struct PageRecord PageRecord; struct PageRecord { Pgno pgno; /* The page number */ char aData[SQLITE_BLOCK_SIZE]; /* Original data for page pgno */ }; /* ** Journal files begin with the following magic string. The data ** was obtained from /dev/random. It is used only as a sanity check. ** ** There are three journal formats (so far). The 1st journal format writes |
︙ | ︙ | |||
221 222 223 224 225 226 227 | ** the journal file after power is restored. If an attempt is then made ** to roll the journal back, the database could be corrupted. The additional ** sanity checking data is an attempt to discover the garbage in the ** journal and ignore it. ** ** The sanity checking information for the 3rd journal format consists ** of a 32-bit checksum on each page of data. The checksum covers both | | | 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | ** the journal file after power is restored. If an attempt is then made ** to roll the journal back, the database could be corrupted. The additional ** sanity checking data is an attempt to discover the garbage in the ** journal and ignore it. ** ** The sanity checking information for the 3rd journal format consists ** of a 32-bit checksum on each page of data. The checksum covers both ** the page number and the SQLITE_BLOCK_SIZE bytes of data for the page. ** This cksum is initialized to a 32-bit random value that appears in the ** journal file right after the header. The random initializer is important, ** because garbage data that appears at the end of a journal is likely ** data that was once in other files that have now been deleted. If the ** garbage data came from an obsolete journal file, the checksums might ** be correct. But by initializing the checksum to random value which ** is different for every journal, we minimize that risk. |
︙ | ︙ | |||
266 267 268 269 270 271 272 | ** The size of the header and of each page in the journal varies according ** to which journal format is being used. The following macros figure out ** the sizes based on format numbers. */ #define JOURNAL_HDR_SZ(X) \ (sizeof(aJournalMagic1) + sizeof(Pgno) + ((X)>=3)*2*sizeof(u32)) #define JOURNAL_PG_SZ(X) \ | | | 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | ** The size of the header and of each page in the journal varies according ** to which journal format is being used. The following macros figure out ** the sizes based on format numbers. */ #define JOURNAL_HDR_SZ(X) \ (sizeof(aJournalMagic1) + sizeof(Pgno) + ((X)>=3)*2*sizeof(u32)) #define JOURNAL_PG_SZ(X) \ (SQLITE_BLOCK_SIZE + sizeof(Pgno) + ((X)>=3)*sizeof(u32)) /* ** Enable reference count tracking here: */ #ifdef SQLITE_TEST int pager_refinfo_enable = 0; static void pager_refinfo(PgHdr *p){ |
︙ | ︙ | |||
544 545 546 547 548 549 550 | } /* Playback the page. Update the in-memory copy of the page ** at the same time, if there is one. */ pPg = pager_lookup(pPager, pgRec.pgno); TRACE2("PLAYBACK %d\n", pgRec.pgno); | | | | > > > | 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 | } /* Playback the page. Update the in-memory copy of the page ** at the same time, if there is one. */ pPg = pager_lookup(pPager, pgRec.pgno); TRACE2("PLAYBACK %d\n", pgRec.pgno); sqliteOsSeek(&pPager->fd, (pgRec.pgno-1)*(off_t)SQLITE_BLOCK_SIZE); rc = sqliteOsWrite(&pPager->fd, pgRec.aData, SQLITE_BLOCK_SIZE); if( pPg ){ /* No page should ever be rolled back that is in use, except for page ** 1 which is held in use in order to keep the lock on the database ** active. */ assert( pPg->nRef==0 || pPg->pgno==1 ); memcpy(PGHDR_TO_DATA(pPg), pgRec.aData, SQLITE_BLOCK_SIZE); memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra); pPg->dirty = 0; pPg->needSync = 0; if( pPager->xCodec ){ pPager->xCodec(pPager->pCodecArg, PGHDR_TO_DATA(pPg), 0); } } return rc; } /* ** Playback the journal and thus restore the database file to ** the state it was in before we started making changes. |
︙ | ︙ | |||
579 580 581 582 583 584 585 | ** in format 3 only. ** * 4 byte big-endian integer which is the initial value for the ** sanity checksum. This field appears in format 3 only. ** * 4 byte integer which is the number of pages to truncate the ** database to during a rollback. ** * Zero or more pages instances, each as follows: ** + 4 byte page number. | | | 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 | ** in format 3 only. ** * 4 byte big-endian integer which is the initial value for the ** sanity checksum. This field appears in format 3 only. ** * 4 byte integer which is the number of pages to truncate the ** database to during a rollback. ** * Zero or more pages instances, each as follows: ** + 4 byte page number. ** + SQLITE_BLOCK_SIZE bytes of data. ** + 4 byte checksum (format 3 only) ** ** When we speak of the journal header, we mean the first 4 bullets above. ** Each entry in the journal is an instance of the 5th bullet. Note that ** bullets 2 and 3 only appear in format-3 journals. ** ** Call the value from the second bullet "nRec". nRec is the number of |
︙ | ︙ | |||
685 686 687 688 689 690 691 | assert( nRec*JOURNAL_PG_SZ(2)+JOURNAL_HDR_SZ(2)==szJ ); } rc = read32bits(format, &pPager->jfd, &mxPg); if( rc!=SQLITE_OK ){ goto end_playback; } assert( pPager->origDbSize==0 || pPager->origDbSize==mxPg ); | | | 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 | assert( nRec*JOURNAL_PG_SZ(2)+JOURNAL_HDR_SZ(2)==szJ ); } rc = read32bits(format, &pPager->jfd, &mxPg); if( rc!=SQLITE_OK ){ goto end_playback; } assert( pPager->origDbSize==0 || pPager->origDbSize==mxPg ); rc = sqliteOsTruncate(&pPager->fd, SQLITE_BLOCK_SIZE*(off_t)mxPg); if( rc!=SQLITE_OK ){ goto end_playback; } pPager->dbSize = mxPg; /* Copy original pages out of the journal and back into the database file. */ |
︙ | ︙ | |||
710 711 712 713 714 715 716 | /* Pages that have been written to the journal but never synced ** where not restored by the loop above. We have to restore those ** pages by reading them back from the original database. */ if( rc==SQLITE_OK ){ PgHdr *pPg; for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ | | | | > > > | | | | 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 | /* Pages that have been written to the journal but never synced ** where not restored by the loop above. We have to restore those ** pages by reading them back from the original database. */ if( rc==SQLITE_OK ){ PgHdr *pPg; for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ char zBuf[SQLITE_BLOCK_SIZE]; if( !pPg->dirty ) continue; if( (int)pPg->pgno <= pPager->origDbSize ){ sqliteOsSeek(&pPager->fd, SQLITE_BLOCK_SIZE*(off_t)(pPg->pgno-1)); rc = sqliteOsRead(&pPager->fd, zBuf, SQLITE_BLOCK_SIZE); if( rc ) break; if( pPager->xCodec ){ pPager->xCodec(pPager->pCodecArg, zBuf, 0); } }else{ memset(zBuf, 0, SQLITE_BLOCK_SIZE); } if( pPg->nRef==0 || memcmp(zBuf, PGHDR_TO_DATA(pPg), SQLITE_BLOCK_SIZE) ){ memcpy(PGHDR_TO_DATA(pPg), zBuf, SQLITE_BLOCK_SIZE); memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra); } pPg->needSync = 0; pPg->dirty = 0; } } |
︙ | ︙ | |||
761 762 763 764 765 766 767 | off_t szJ; /* Size of the full journal */ int nRec; /* Number of Records */ int i; /* Loop counter */ int rc; /* Truncate the database back to its original size. */ | | | 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 | off_t szJ; /* Size of the full journal */ int nRec; /* Number of Records */ int i; /* Loop counter */ int rc; /* Truncate the database back to its original size. */ rc = sqliteOsTruncate(&pPager->fd, SQLITE_BLOCK_SIZE*(off_t)pPager->ckptSize); pPager->dbSize = pPager->ckptSize; /* Figure out how many records are in the checkpoint journal. */ assert( pPager->ckptInUse && pPager->journalOpen ); sqliteOsSeek(&pPager->cpfd, 0); nRec = pPager->ckptNRec; |
︙ | ︙ | |||
999 1000 1001 1002 1003 1004 1005 | if( pPager->dbSize>=0 ){ return pPager->dbSize; } if( sqliteOsFileSize(&pPager->fd, &n)!=SQLITE_OK ){ pPager->errMask |= PAGER_ERR_DISK; return 0; } | | | 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 | if( pPager->dbSize>=0 ){ return pPager->dbSize; } if( sqliteOsFileSize(&pPager->fd, &n)!=SQLITE_OK ){ pPager->errMask |= PAGER_ERR_DISK; return 0; } n /= SQLITE_BLOCK_SIZE; if( pPager->state!=SQLITE_UNLOCK ){ pPager->dbSize = n; } return n; } /* |
︙ | ︙ | |||
1027 1028 1029 1030 1031 1032 1033 | rc = pager_errcode(pPager); return rc; } if( nPage>=(unsigned)pPager->dbSize ){ return SQLITE_OK; } syncJournal(pPager); | | | 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 | rc = pager_errcode(pPager); return rc; } if( nPage>=(unsigned)pPager->dbSize ){ return SQLITE_OK; } syncJournal(pPager); rc = sqliteOsTruncate(&pPager->fd, SQLITE_BLOCK_SIZE*(off_t)nPage); if( rc==SQLITE_OK ){ pPager->dbSize = nPage; } return rc; } /* |
︙ | ︙ | |||
1234 1235 1236 1237 1238 1239 1240 | Pager *pPager; int rc; if( pList==0 ) return SQLITE_OK; pPager = pList->pPager; while( pList ){ assert( pList->dirty ); | | > > > | > > > | 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 | Pager *pPager; int rc; if( pList==0 ) return SQLITE_OK; pPager = pList->pPager; while( pList ){ assert( pList->dirty ); sqliteOsSeek(&pPager->fd, (pList->pgno-1)*(off_t)SQLITE_BLOCK_SIZE); if( pPager->xCodec ){ pPager->xCodec(pPager->pCodecArg, PGHDR_TO_DATA(pList), 1); } rc = sqliteOsWrite(&pPager->fd, PGHDR_TO_DATA(pList), SQLITE_BLOCK_SIZE); if( pPager->xCodec ){ pPager->xCodec(pPager->pCodecArg, PGHDR_TO_DATA(pList), 0); } if( rc ) return rc; pList->dirty = 0; pList = pList->pDirty; } return SQLITE_OK; } |
︙ | ︙ | |||
1359 1360 1361 1362 1363 1364 1365 | } if( pPg==0 ){ /* The requested page is not in the page cache. */ int h; pPager->nMiss++; if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 ){ /* Create a new page */ | | | 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 | } if( pPg==0 ){ /* The requested page is not in the page cache. */ int h; pPager->nMiss++; if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 ){ /* Create a new page */ pPg = sqliteMallocRaw( sizeof(*pPg) + SQLITE_BLOCK_SIZE + sizeof(u32) + pPager->nExtra ); if( pPg==0 ){ pager_unwritelock(pPager); pPager->errMask |= PAGER_ERR_MEM; return SQLITE_NOMEM; } memset(pPg, 0, sizeof(*pPg)); |
︙ | ︙ | |||
1491 1492 1493 1494 1495 1496 1497 | if( pPager->dbSize<0 ) sqlitepager_pagecount(pPager); if( pPager->errMask!=0 ){ sqlitepager_unref(PGHDR_TO_DATA(pPg)); rc = pager_errcode(pPager); return rc; } if( pPager->dbSize<(int)pgno ){ | | | | | | > > | 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 | if( pPager->dbSize<0 ) sqlitepager_pagecount(pPager); if( pPager->errMask!=0 ){ sqlitepager_unref(PGHDR_TO_DATA(pPg)); rc = pager_errcode(pPager); return rc; } if( pPager->dbSize<(int)pgno ){ memset(PGHDR_TO_DATA(pPg), 0, SQLITE_BLOCK_SIZE); }else{ int rc; sqliteOsSeek(&pPager->fd, (pgno-1)*(off_t)SQLITE_BLOCK_SIZE); rc = sqliteOsRead(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_BLOCK_SIZE); if( rc!=SQLITE_OK ){ off_t fileSize; if( sqliteOsFileSize(&pPager->fd,&fileSize)!=SQLITE_OK || fileSize>=pgno*SQLITE_BLOCK_SIZE ){ sqlitepager_unref(PGHDR_TO_DATA(pPg)); return rc; }else{ memset(PGHDR_TO_DATA(pPg), 0, SQLITE_BLOCK_SIZE); } }else if( pPager->xCodec ){ pPager->xCodec(pPager->pCodecArg, PGHDR_TO_DATA(pPg), 0); } } }else{ /* The requested page is in the page cache. */ pPager->nHit++; page_ref(pPg); } |
︙ | ︙ | |||
1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 | saved = *(u32*)PGHDR_TO_EXTRA(pPg); store32bits(cksum, pPg, SQLITE_PAGE_SIZE); szPg = SQLITE_PAGE_SIZE+8; }else{ szPg = SQLITE_PAGE_SIZE+4; } store32bits(pPg->pgno, pPg, -4); rc = sqliteOsWrite(&pPager->jfd, &((char*)pData)[-4], szPg); if( journal_format>=JOURNAL_FORMAT_3 ){ *(u32*)PGHDR_TO_EXTRA(pPg) = saved; } if( rc!=SQLITE_OK ){ sqlitepager_rollback(pPager); pPager->errMask |= PAGER_ERR_FULL; return rc; | > > > > > > | 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 | saved = *(u32*)PGHDR_TO_EXTRA(pPg); store32bits(cksum, pPg, SQLITE_PAGE_SIZE); szPg = SQLITE_PAGE_SIZE+8; }else{ szPg = SQLITE_PAGE_SIZE+4; } store32bits(pPg->pgno, pPg, -4); if( pPager->xCodec ){ pPager->xCodec(pPager->pCodecArg, pData, 1); } rc = sqliteOsWrite(&pPager->jfd, &((char*)pData)[-4], szPg); if( pPager->xCodec ){ pPager->xCodec(pPager->pCodecArg, pData, 0); } if( journal_format>=JOURNAL_FORMAT_3 ){ *(u32*)PGHDR_TO_EXTRA(pPg) = saved; } if( rc!=SQLITE_OK ){ sqlitepager_rollback(pPager); pPager->errMask |= PAGER_ERR_FULL; return rc; |
︙ | ︙ | |||
1819 1820 1821 1822 1823 1824 1825 | ** then write the current page to the checkpoint journal. Note that ** the checkpoint journal always uses the simplier format 2 that lacks ** checksums. The header is also omitted from the checkpoint journal. */ if( pPager->ckptInUse && !pPg->inCkpt && (int)pPg->pgno<=pPager->ckptSize ){ assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize ); store32bits(pPg->pgno, pPg, -4); | | | 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 | ** then write the current page to the checkpoint journal. Note that ** the checkpoint journal always uses the simplier format 2 that lacks ** checksums. The header is also omitted from the checkpoint journal. */ if( pPager->ckptInUse && !pPg->inCkpt && (int)pPg->pgno<=pPager->ckptSize ){ assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize ); store32bits(pPg->pgno, pPg, -4); rc = sqliteOsWrite(&pPager->cpfd, &((char*)pData)[-4], SQLITE_BLOCK_SIZE+4); if( rc!=SQLITE_OK ){ sqlitepager_rollback(pPager); pPager->errMask |= PAGER_ERR_FULL; return rc; } pPager->ckptNRec++; assert( pPager->aInCkpt!=0 ); |
︙ | ︙ | |||
1861 1862 1863 1864 1865 1866 1867 | void *pPage; int rc; rc = sqlitepager_get(pPager, pgno, &pPage); if( rc==SQLITE_OK ){ rc = sqlitepager_write(pPage); if( rc==SQLITE_OK ){ | | | 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 | void *pPage; int rc; rc = sqlitepager_get(pPager, pgno, &pPage); if( rc==SQLITE_OK ){ rc = sqlitepager_write(pPage); if( rc==SQLITE_OK ){ memcpy(pPage, pData, SQLITE_BLOCK_SIZE); } sqlitepager_unref(pPage); } return rc; } /* |
︙ | ︙ | |||
2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 | /* ** Return the full pathname of the database file. */ const char *sqlitepager_filename(Pager *pPager){ return pPager->zFilename; } #ifdef SQLITE_TEST /* ** Print a listing of all referenced pages and their ref count. */ void sqlitepager_refdump(Pager *pPager){ PgHdr *pPg; | > > > > > > > > > > > > | 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 | /* ** Return the full pathname of the database file. */ const char *sqlitepager_filename(Pager *pPager){ return pPager->zFilename; } /* ** Set the codec for this pager */ void sqlitepager_set_codec( Pager *pPager, void (*xCodec)(void*,void*,int), void *pCodecArg ){ pPager->xCodec = xCodec; pPager->pCodecArg = pCodecArg; } #ifdef SQLITE_TEST /* ** Print a listing of all referenced pages and their ref count. */ void sqlitepager_refdump(Pager *pPager){ PgHdr *pPg; |
︙ | ︙ |
Changes to src/pager.h.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite page cache ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** | | > > | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite page cache ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** ** @(#) $Id: pager.h,v 1.24 2004/02/09 01:20:37 drh Exp $ */ /* ** The size of one page ** ** You can change this value to another (reasonable) power of two ** such as 512, 2048, 4096, or 8192 and things will still work. But ** experiments show that a page size of 1024 gives the best speed. ** (The speed differences are minimal.) */ #ifndef SQLITE_PAGE_SIZE #define SQLITE_PAGE_SIZE 1024 #endif /* ** Maximum number of pages in one database. (This is a limitation of ** imposed by 4GB files size limits.) */ #define SQLITE_MAX_PAGE 1073741823 |
︙ | ︙ | |||
71 72 73 74 75 76 77 78 79 80 81 82 83 | int sqlitepager_ckpt_rollback(Pager*); void sqlitepager_dont_rollback(void*); void sqlitepager_dont_write(Pager*, Pgno); int *sqlitepager_stats(Pager*); void sqlitepager_set_safety_level(Pager*,int); const char *sqlitepager_filename(Pager*); int sqlitepager_rename(Pager*, const char *zNewName); #ifdef SQLITE_TEST void sqlitepager_refdump(Pager*); int pager_refinfo_enable; int journal_format; #endif | > | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | int sqlitepager_ckpt_rollback(Pager*); void sqlitepager_dont_rollback(void*); void sqlitepager_dont_write(Pager*, Pgno); int *sqlitepager_stats(Pager*); void sqlitepager_set_safety_level(Pager*,int); const char *sqlitepager_filename(Pager*); int sqlitepager_rename(Pager*, const char *zNewName); void sqlitepager_set_codec(Pager*,void(*)(void*,void*,int),void*); #ifdef SQLITE_TEST void sqlitepager_refdump(Pager*); int pager_refinfo_enable; int journal_format; #endif |