From: drh Date: Thu, 12 Aug 2010 02:41:12 +0000 (+0000) Subject: Increase the maximum page size from 32k to 64k. X-Git-Tag: version-3.7.2~47 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b2eced5de2ed4a5f030ce3d8e9e3ccb2e0abc226;p=thirdparty%2Fsqlite.git Increase the maximum page size from 32k to 64k. FossilOrigin-Name: 45362437d491fbe0f033a67b398f8ba68cbf1b3b --- diff --git a/manifest b/manifest index 6f55fe208d..c85376b665 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\scoverage\sof\spager.c. -D 2010-08-11T18:56:46 +C Increase\sthe\smaximum\spage\ssize\sfrom\s32k\sto\s64k. +D 2010-08-12T02:41:12 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -113,9 +113,9 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 51d83300fe0baee39405c416ceb19a58ed30a8ed F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff -F src/btree.c 63eebba7bd87207556670139eae5ef6c1f8bb416 +F src/btree.c 042a5c0a6a8b6121019b258737872b1ab703d39e F src/btree.h b4ba2fdf6b64c7c376bdfffa826af6b786b151d9 -F src/btreeInt.h b0c87f6725b06a0aa194a6d25d54b16ce9d6e291 +F src/btreeInt.h 5b034ff54800046cc5870605d683ac1f9134bd99 F src/build.c 0018d49629fc4807100c988dd191dd95e185bb38 F src/callback.c da3c38d0ef5d7f04fae371e519bda61aa9cb1704 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac @@ -156,8 +156,8 @@ F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e F src/os_unix.c 11194cbcf6a57456e58022dc537ab8c3497d9bb9 F src/os_win.c 51cb62f76262d961ea4249489383d714501315a7 -F src/pager.c 3fb56c4d03798058e5cf57b668468fa616e20bac -F src/pager.h 80726162dc3942f59ab27b738fb667b9ba0a89d5 +F src/pager.c 39be42c3234a4ea51ddf185a47a91f31a0439fd1 +F src/pager.h 985a83d35b0cfa8e1c23ef91ed5cdb9bde73695a F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07 F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 @@ -173,12 +173,12 @@ F src/shell.c 8517fc1f9c59ae4007e6cc8b9af91ab231ea2056 F src/sqlite.h.in 2d72a6242df41c517e38eec8791abcf5484a36f1 F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89 F src/sqliteInt.h e33b15e8176442bf7484f0e716edfd1ce03b2979 -F src/sqliteLimit.h 196e2f83c3b444c4548fc1874f52f84fdbda40f3 +F src/sqliteLimit.h 4ae9b005144400984cbcafd4d7c09659bb2af92a F src/status.c 496913d4e8441195f6f2a75b1c95993a45b9b30b F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c 5cd96419fb6c771006f064196ccc70c29d01bec7 F src/test1.c 0bfcda72f9f8ab5c0e90fac05cc22c1c21131ddf -F src/test2.c e3f564ab1e9fd0b47b0c9e23e7054e38bf0836cf +F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 4c21700c73a890a47fc685c1097bfb661346ac94 F src/test4.c 0528360b5025688002a5feb6be906ddce52eaaee F src/test5.c e1a19845625144caf038031234a12185e40d315c @@ -210,7 +210,7 @@ F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6 F src/test_stat.c dcabb7d39da058cbfc9ddc427cd92fbf14822b28 F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_thread.c bedd05cad673dba53326f3aa468cc803038896c0 -F src/test_vfs.c 7e291f85256516ebde6633bc381ff7eedfa30234 +F src/test_vfs.c 702e52636113f6b9721da90ef1bf26e07fff414d F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 F src/trigger.c b8bedb9c0084ceb51a40f54fcca2ce048c8de852 @@ -227,7 +227,7 @@ F src/vdbeblob.c 258a6010ba7a82b72b327fb24c55790655689256 F src/vdbemem.c e5673f81a2381b35c60e73ef0a8502be2ab1041e F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2 F src/vtab.c 0e8e0cb30dffb078367e843e84e37ef99236c7e4 -F src/wal.c 582acbaa606c748675fafff516ec1b34a7bdae62 +F src/wal.c c79ae356eb124ba2ca4e9842e30bc1fa9c0ef273 F src/wal.h 96669b645e27cd5a111ba59f0cae7743a207bc3c F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c 7db3e41c2a846f9deeb24f1bbb75461b4010b7b5 @@ -539,7 +539,7 @@ F test/notify3.test d60923e186e0900f4812a845fcdfd8eea096e33a F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec -F test/pager1.test 20457c96ab1d4e876d335cfd6ddd0f539bda3f81 +F test/pager1.test 9a7650f95bc84ef2fa4c2db87f9676d2641f9829 F test/pager2.test 9edc1584cbc8ecd3b34dbcc8e86467bf05caa27f F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f F test/pagerfault.test 495ab0a0ed30aebe7e4278fcee148986085d4c8b @@ -782,7 +782,7 @@ F test/vtabE.test 7c4693638d7797ce2eda17af74292b97e705cc61 F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d -F test/wal.test 1891e6f72dd437a1c2a48091aa9182ba17a8f780 +F test/wal.test 0369e9ef9ac9b0f9a4a274819d83489578ccaef1 F test/wal2.test 223f3e14d475730af772a7f5862d4bcfa7565c3a F test/wal3.test 695ea0f6c516423c611891df9a285aacd33344e3 F test/wal4.test 3404b048fa5e10605facaf70384e6d2943412e30 @@ -843,7 +843,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P eaaca669a4afc83906806b22365b010c83bc3db8 -R 2966f30f98145ee75718d7c3465c6545 -U dan -Z cd90e6256916f41a20463762a4c0c757 +P 2fa05d01b6b11788a5b73d203fcac9d4a4ba9fd8 +R 68189c2924cc1a955c4daa7396f7f071 +U drh +Z ea2561c5cb1a509ae1c92e5b10fbf288 diff --git a/manifest.uuid b/manifest.uuid index 3bfa43329f..fe0d59964d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2fa05d01b6b11788a5b73d203fcac9d4a4ba9fd8 \ No newline at end of file +45362437d491fbe0f033a67b398f8ba68cbf1b3b \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index dc32895415..312f1ef987 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1155,6 +1155,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf ); gap = pPage->cellOffset + 2*pPage->nCell; top = get2byte(&data[hdr+5]); + if( top==0 ) top = 65536; if( gap>top ) return SQLITE_CORRUPT_BKPT; testcase( gap+2==top ); testcase( gap+1==top ); @@ -1165,6 +1166,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ rc = defragmentPage(pPage); if( rc ) return rc; top = get2byte(&data[hdr+5]); + if( top==0 ) top = 65536; }else if( gap+2<=top ){ /* Search the freelist looking for a free slot big enough to satisfy ** the request. The allocation is made from the first free slot in @@ -1207,6 +1209,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ rc = defragmentPage(pPage); if( rc ) return rc; top = get2byte(&data[hdr+5]); + if( top==0 ) top = 65536; assert( gap+nByte<=top ); } @@ -1372,10 +1375,10 @@ static int btreeInitPage(MemPage *pPage){ u8 hdr; /* Offset to beginning of page header */ u8 *data; /* Equal to pPage->aData */ BtShared *pBt; /* The main btree structure */ - u16 usableSize; /* Amount of usable space on each page */ - u16 cellOffset; /* Offset from start of page to first cell pointer */ - u16 nFree; /* Number of unused bytes on the page */ - u16 top; /* First byte of the cell content area */ + int usableSize; /* Amount of usable space on each page */ + int cellOffset; /* Offset from start of page to first cell pointer */ + int nFree; /* Number of unused bytes on the page */ + int top; /* First byte of the cell content area */ int iCellFirst; /* First allowable cell or freeblock offset */ int iCellLast; /* Last possible cell or freeblock offset */ @@ -1384,12 +1387,13 @@ static int btreeInitPage(MemPage *pPage){ hdr = pPage->hdrOffset; data = pPage->aData; if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT; - assert( pBt->pageSize>=512 && pBt->pageSize<=32768 ); - pPage->maskPage = pBt->pageSize - 1; + assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); + pPage->maskPage = (u16)(pBt->pageSize - 1); pPage->nOverflow = 0; usableSize = pBt->usableSize; pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf; top = get2byte(&data[hdr+5]); + if( top==0 ) top = 65536; pPage->nCell = get2byte(&data[hdr+3]); if( pPage->nCell>MX_CELL(pBt) ){ /* To many cells for a single page. The page must be corrupt */ @@ -1493,8 +1497,8 @@ static void zeroPage(MemPage *pPage, int flags){ pPage->hdrOffset = hdr; pPage->cellOffset = first; pPage->nOverflow = 0; - assert( pBt->pageSize>=512 && pBt->pageSize<=32768 ); - pPage->maskPage = pBt->pageSize - 1; + assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); + pPage->maskPage = (u16)(pBt->pageSize - 1); pPage->nCell = 0; pPage->isInit = 1; } @@ -1802,7 +1806,7 @@ int sqlite3BtreeOpen( #ifdef SQLITE_SECURE_DELETE pBt->secureDelete = 1; #endif - pBt->pageSize = get2byte(&zDbHeader[16]); + pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16); if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){ pBt->pageSize = 0; @@ -2116,7 +2120,7 @@ int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){ ((pageSize-1)&pageSize)==0 ){ assert( (pageSize & 7)==0 ); assert( !pBt->pPage1 && !pBt->pCursor ); - pBt->pageSize = (u16)pageSize; + pBt->pageSize = (u32)pageSize; freeTempSpace(pBt); } rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); @@ -2310,9 +2314,10 @@ static int lockBtree(BtShared *pBt){ if( memcmp(&page1[21], "\100\040\040",3)!=0 ){ goto page1_init_failed; } - pageSize = get2byte(&page1[16]); - if( ((pageSize-1)&pageSize)!=0 || pageSize<512 || - (SQLITE_MAX_PAGE_SIZE<32768 && pageSize>SQLITE_MAX_PAGE_SIZE) + pageSize = (page1[16]<<8) | (page1[17]<<16); + if( ((pageSize-1)&pageSize)!=0 + || pageSize>SQLITE_MAX_PAGE_SIZE + || pageSize<=256 ){ goto page1_init_failed; } @@ -2326,8 +2331,8 @@ static int lockBtree(BtShared *pBt){ ** again with the correct page-size. */ releasePage(pPage1); - pBt->usableSize = (u16)usableSize; - pBt->pageSize = (u16)pageSize; + pBt->usableSize = (u32)usableSize; + pBt->pageSize = (u32)pageSize; freeTempSpace(pBt); rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, pageSize-usableSize); @@ -2340,8 +2345,8 @@ static int lockBtree(BtShared *pBt){ if( usableSize<480 ){ goto page1_init_failed; } - pBt->pageSize = (u16)pageSize; - pBt->usableSize = (u16)usableSize; + pBt->pageSize = (u32)pageSize; + pBt->usableSize = (u32)usableSize; #ifndef SQLITE_OMIT_AUTOVACUUM pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0); pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0); @@ -2417,7 +2422,8 @@ static int newDatabase(BtShared *pBt){ if( rc ) return rc; memcpy(data, zMagicHeader, sizeof(zMagicHeader)); assert( sizeof(zMagicHeader)==16 ); - put2byte(&data[16], pBt->pageSize); + data[16] = (pBt->pageSize>>8)&0xff; + data[17] = (pBt->pageSize>>16)&0xff; data[18] = 1; data[19] = 1; assert( pBt->usableSize<=pBt->pageSize && pBt->usableSize+255>=pBt->pageSize); @@ -4428,9 +4434,9 @@ int sqlite3BtreeMovetoUnpacked( pCur->validNKey = 1; pCur->info.nKey = nCellKey; }else{ - /* The maximum supported page-size is 32768 bytes. This means that + /* The maximum supported page-size is 65536 bytes. This means that ** the maximum number of record bytes stored on an index B-Tree - ** page is at most 8198 bytes, which may be stored as a 2-byte + ** page is less than 16384 bytes and may be stored as a 2-byte ** varint. This information is used to attempt to avoid parsing ** the entire cell by checking for the cases where the record is ** stored entirely within the b-tree page by inspecting the first @@ -5399,7 +5405,7 @@ static void insertCell( if( *pRC ) return; assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); - assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=5460 ); + assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=10921 ); assert( pPage->nOverflow<=ArraySize(pPage->aOvfl) ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); /* The cell should normally be sized correctly. However, when moving a @@ -5479,12 +5485,12 @@ static void assemblePage( assert( pPage->nOverflow==0 ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - assert( nCell>=0 && nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=5460 ); + assert( nCell>=0 && nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=10921); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); /* Check that the page has just been zeroed by zeroPage() */ assert( pPage->nCell==0 ); - assert( get2byte(&data[hdr+5])==nUsable ); + assert( get2byte(&data[hdr+5])==(nUsable&0xffff) ); pCellptr = &data[pPage->cellOffset + nCell*2]; cellbody = nUsable; @@ -7659,7 +7665,8 @@ static int checkTreePage( if( hit==0 ){ pCheck->mallocFailed = 1; }else{ - u16 contentOffset = get2byte(&data[hdr+5]); + int contentOffset = get2byte(&data[hdr+5]); + if( contentOffset==0 ) contentOffset = 65536; assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */ memset(hit+contentOffset, 0, usableSize-contentOffset); memset(hit, 1, contentOffset); diff --git a/src/btreeInt.h b/src/btreeInt.h index 8b68d7b316..7b46bcebbd 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -46,7 +46,7 @@ ** ** The file is divided into pages. The first page is called page 1, ** the second is page 2, and so forth. A page number of zero indicates -** "no such page". The page size can be any power of 2 between 512 and 32768. +** "no such page". The page size can be any power of 2 between 512 and 65536. ** Each page can be either a btree page, a freelist page, an overflow ** page, or a pointer-map page. ** @@ -413,14 +413,14 @@ struct BtShared { u8 autoVacuum; /* True if auto-vacuum is enabled */ u8 incrVacuum; /* True if incr-vacuum is enabled */ #endif - u16 pageSize; /* Total number of bytes on a page */ - u16 usableSize; /* Number of usable bytes on each page */ u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */ u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */ u16 maxLeaf; /* Maximum local payload in a LEAFDATA table */ u16 minLeaf; /* Minimum local payload in a LEAFDATA table */ u8 inTransaction; /* Transaction state */ u8 doNotUseWAL; /* If true, do not open write-ahead-log file */ + u32 pageSize; /* Total number of bytes on a page */ + u32 usableSize; /* Number of usable bytes on each page */ int nTransaction; /* Number of open transactions (read + write) */ u32 nPage; /* Number of pages in the database */ void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */ diff --git a/src/pager.c b/src/pager.c index 33a61de111..12f45b5c18 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1505,7 +1505,6 @@ static int readJournalHdr( if( pPager->journalOff==0 ){ u32 iPageSize; /* Page-size field of journal header */ u32 iSectorSize; /* Sector-size field of journal header */ - u16 iPageSize16; /* Copy of iPageSize in 16-bit variable */ /* Read the page-size and sector-size journal header fields. */ if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize)) @@ -1535,10 +1534,8 @@ static int readJournalHdr( ** Use a testcase() macro to make sure that malloc failure within ** PagerSetPagesize() is tested. */ - iPageSize16 = (u16)iPageSize; - rc = sqlite3PagerSetPagesize(pPager, &iPageSize16, -1); + rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1); testcase( rc!=SQLITE_OK ); - assert( rc!=SQLITE_OK || iPageSize16==(u16)iPageSize ); /* Update the assumed sector-size to match the value used by ** the process that created this journal. If this journal was @@ -3356,7 +3353,7 @@ void sqlite3PagerSetBusyhandler( ** function was called, or because the memory allocation attempt failed, ** then *pPageSize is set to the old, retained page size before returning. */ -int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize, int nReserve){ +int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){ /* It is not possible to do a full assert_pager_state() here, as this ** function may be called from within PagerOpen(), before the state ** of the Pager object is internally consistent. @@ -3367,7 +3364,7 @@ int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize, int nReserve){ ** is a no-op for that case anyhow. */ - u16 pageSize = *pPageSize; + u32 pageSize = *pPageSize; assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) ); if( (pPager->memDb==0 || pPager->dbSize==0) && sqlite3PcacheRefCount(pPager->pPCache)==0 @@ -3392,7 +3389,7 @@ int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize, int nReserve){ } } - *pPageSize = (u16)pPager->pageSize; + *pPageSize = pPager->pageSize; if( nReserve<0 ) nReserve = pPager->nReserve; assert( nReserve>=0 && nReserve<1000 ); pPager->nReserve = (i16)nReserve; @@ -4184,7 +4181,7 @@ int sqlite3PagerOpen( int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ int noReadlock = (flags & PAGER_NO_READLOCK)!=0; /* True to omit read-lock */ int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ - u16 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ + u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ /* Figure out how much space is required for each journal file-handle ** (there are two of them, the main journal and the sub-journal). This @@ -4319,7 +4316,7 @@ int sqlite3PagerOpen( if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){ szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE; }else{ - szPageDflt = (u16)pPager->sectorSize; + szPageDflt = (u32)pPager->sectorSize; } } #ifdef SQLITE_ENABLE_ATOMIC_WRITE diff --git a/src/pager.h b/src/pager.h index 3b724c4ba8..ad9144aecd 100644 --- a/src/pager.h +++ b/src/pager.h @@ -99,7 +99,7 @@ int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); /* Functions used to configure a Pager object. */ void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *); -int sqlite3PagerSetPagesize(Pager*, u16*, int); +int sqlite3PagerSetPagesize(Pager*, u32*, int); int sqlite3PagerMaxPageCount(Pager*, int); void sqlite3PagerSetCachesize(Pager*, int); void sqlite3PagerSetSafetyLevel(Pager*,int,int); diff --git a/src/sqliteLimit.h b/src/sqliteLimit.h index 1dc5d675da..98cddabaf0 100644 --- a/src/sqliteLimit.h +++ b/src/sqliteLimit.h @@ -133,9 +133,8 @@ # define SQLITE_MAX_VARIABLE_NUMBER 999 #endif -/* Maximum page size. The upper bound on this value is 32768. This a limit -** imposed by the necessity of storing the value in a 2-byte unsigned integer -** and the fact that the page size must be a power of 2. +/* Maximum page size. The upper bound on this value is 65536. This a limit +** imposed by the use of 16-bit offsets within each page. ** ** If this limit is changed, then the compiled library is technically ** incompatible with an SQLite library compiled with a different limit. If @@ -145,7 +144,7 @@ ** lead to database corruption. */ #ifndef SQLITE_MAX_PAGE_SIZE -# define SQLITE_MAX_PAGE_SIZE 32768 +# define SQLITE_MAX_PAGE_SIZE 65536 #endif diff --git a/src/test2.c b/src/test2.c index 520ad7306d..fa7dd76ce4 100644 --- a/src/test2.c +++ b/src/test2.c @@ -72,7 +72,7 @@ static int pager_open( int argc, /* Number of arguments */ const char **argv /* Text of each argument */ ){ - u16 pageSize; + u32 pageSize; Pager *pPager; int nPage; int rc; diff --git a/src/test_vfs.c b/src/test_vfs.c index f577bf5106..c606cfbe5c 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -1000,7 +1000,7 @@ static int testvfs_obj_cmd( int n; u8 *a = Tcl_GetByteArrayFromObj(objv[3], &n); int pgsz = pBuffer->pgsz; - if( pgsz==0 ) pgsz = 32768; + if( pgsz==0 ) pgsz = 65536; for(i=0; i*pgszaPage[i]; i++){ int pgsz = pBuffer->pgsz; - if( pgsz==0 ) pgsz = 32768; + if( pgsz==0 ) pgsz = 65536; Tcl_AppendObjToObj(pObj, Tcl_NewByteArrayObj(pBuffer->aPage[i], pgsz)); } Tcl_SetObjResult(interp, pObj); diff --git a/src/wal.c b/src/wal.c index 5924a63756..97e3205bb1 100644 --- a/src/wal.c +++ b/src/wal.c @@ -410,7 +410,7 @@ struct Wal { u32 iCallback; /* Value to pass to log callback (or 0) */ int nWiData; /* Size of array apWiData */ volatile u32 **apWiData; /* Pointer to wal-index content in memory */ - u16 szPage; /* Database page size */ + u32 szPage; /* Database page size */ i16 readLock; /* Which read lock is being held. -1 for none */ u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ u8 writeLock; /* True if in a write transaction */ @@ -1081,7 +1081,7 @@ static int walIndexRecover(Wal *pWal){ goto finished; } pWal->hdr.bigEndCksum = (u8)(magic&0x00000001); - pWal->szPage = (u16)szPage; + pWal->szPage = szPage; pWal->nCkpt = sqlite3Get4byte(&aBuf[12]); memcpy(&pWal->hdr.aSalt, &aBuf[16], 8); @@ -1131,7 +1131,7 @@ static int walIndexRecover(Wal *pWal){ if( nTruncate ){ pWal->hdr.mxFrame = iFrame; pWal->hdr.nPage = nTruncate; - pWal->hdr.szPage = (u16)szPage; + pWal->hdr.szPage = (szPage>=0x10000) ? (szPage>>16) : szPage; aFrameCksum[0] = pWal->hdr.aFrameCksum[0]; aFrameCksum[1] = pWal->hdr.aFrameCksum[1]; } @@ -1516,7 +1516,7 @@ static int walCheckpoint( u8 *zBuf /* Temporary buffer to use */ ){ int rc; /* Return code */ - int szPage = pWal->hdr.szPage; /* Database page-size */ + int szPage; /* Database page-size */ WalIterator *pIter = 0; /* Wal iterator context */ u32 iDbpage = 0; /* Next database page to write */ u32 iFrame = 0; /* Wal frame containing data for iDbpage */ @@ -1525,6 +1525,8 @@ static int walCheckpoint( int i; /* Loop counter */ volatile WalCkptInfo *pInfo; /* The checkpoint status information */ + szPage = pWal->hdr.szPage; + if( szPage<512 ) szPage <<= 16; if( pWal->hdr.mxFrame==0 ) return SQLITE_OK; /* Allocate the iterator */ @@ -1535,7 +1537,7 @@ static int walCheckpoint( assert( pIter ); /*** TODO: Move this test out to the caller. Make it an assert() here ***/ - if( pWal->hdr.szPage!=nBuf ){ + if( szPage!=nBuf ){ rc = SQLITE_CORRUPT_BKPT; goto walcheckpoint_out; } @@ -1727,6 +1729,7 @@ static int walIndexTryHdr(Wal *pWal, int *pChanged){ *pChanged = 1; memcpy(&pWal->hdr, &h1, sizeof(WalIndexHdr)); pWal->szPage = pWal->hdr.szPage; + if( pWal->szPage<512 ) pWal->szPage <<= 16; } /* The header was successfully read. Return zero. */ @@ -2156,7 +2159,11 @@ int sqlite3WalRead( ** required page. Read and return data from the log file. */ if( iRead ){ - i64 iOffset = walFrameOffset(iRead, pWal->hdr.szPage) + WAL_FRAME_HDRSIZE; + int sz; + i64 iOffset; + sz = pWal->hdr.szPage; + if( sz<512 ) sz <<= 16; + iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE; *pInWal = 1; /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ return sqlite3OsRead(pWal->pWalFd, pOut, nOut, iOffset); @@ -2439,7 +2446,7 @@ int sqlite3WalFrames( sqlite3Put4byte(&aWalHdr[24], aCksum[0]); sqlite3Put4byte(&aWalHdr[28], aCksum[1]); - pWal->szPage = (u16)szPage; + pWal->szPage = szPage; pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN; pWal->hdr.aFrameCksum[0] = aCksum[0]; pWal->hdr.aFrameCksum[1] = aCksum[1]; @@ -2534,7 +2541,7 @@ int sqlite3WalFrames( if( rc==SQLITE_OK ){ /* Update the private copy of the header. */ - pWal->hdr.szPage = (u16)szPage; + pWal->hdr.szPage = szPage>=0x10000 ? (szPage >> 16) : szPage; pWal->hdr.mxFrame = iFrame; if( isCommit ){ pWal->hdr.iChange++; diff --git a/test/pager1.test b/test/pager1.test index 330bb69a7f..9ddc6987cb 100644 --- a/test/pager1.test +++ b/test/pager1.test @@ -502,7 +502,7 @@ foreach {tn ofst value result} { 7 24 511 {1 2 3 4} 8 24 513 {1 2 3 4} - 9 24 65536 {1 2 3 4} + 9 24 131072 {1 2 3 4} 10 32 65536 {1 2} } { diff --git a/test/wal.test b/test/wal.test index 59097dc740..96bd05ad5e 100644 --- a/test/wal.test +++ b/test/wal.test @@ -1239,7 +1239,8 @@ foreach {tn pgsz works} { 7 8192 1 8 16384 1 9 32768 1 - 10 65536 0 + 10 65536 1 + 11 131072 0 11 1016 0 } {