]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Factor out btree test logic into a separate test_btree.c file. (CVS 3928)
authordrh <drh@noemail.net>
Sat, 5 May 2007 18:39:25 +0000 (18:39 +0000)
committerdrh <drh@noemail.net>
Sat, 5 May 2007 18:39:25 +0000 (18:39 +0000)
FossilOrigin-Name: d51274f1cc3a75f6a03e90259ce829ac1dacf78f

Makefile.in
main.mk
manifest
manifest.uuid
src/btree.c
src/btreeInt.h
src/test1.c
src/test_btree.c [new file with mode: 0644]
src/vdbeblob.c
test/shared.test

index d36e86681b6be7ffd37d07fe7f83fd0239a4a6a7..23839370f915539fb554a728238fa07f2b11c7bc 100644 (file)
@@ -224,6 +224,7 @@ TESTSRC = \
   $(TOP)/src/test9.c \
   $(TOP)/src/test_autoext.c \
   $(TOP)/src/test_async.c \
+  $(TOP)/src/test_btree.c \
   $(TOP)/src/test_hexio.c \
   $(TOP)/src/test_md5.c \
   $(TOP)/src/test_schema.c \
diff --git a/main.mk b/main.mk
index c8b72d44b7b55eb67d207dd838ecfa2731c13959..671366b4f154c8c193927153b69e5a83554b64e4 100644 (file)
--- a/main.mk
+++ b/main.mk
@@ -180,6 +180,7 @@ TESTSRC = \
   $(TOP)/src/test9.c \
   $(TOP)/src/test_autoext.c \
   $(TOP)/src/test_async.c \
+  $(TOP)/src/test_btree.c \
   $(TOP)/src/test_hexio.c \
   $(TOP)/src/test_md5.c \
   $(TOP)/src/test_schema.c \
index 1566a6e3f704d7c6c374f7a3da7a058514323b66..03a2f3d5466af1212d2d3cf4ab930f580ce08f92 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,6 +1,6 @@
-C Fix\sa\ssprintf()\sproblem\sintroduced\sby\s(3916).\s(CVS\s3927)
-D 2007-05-05T12:06:24
-F Makefile.in 80d63bf2c61619ae0e29795948ec19e79f91acc3
+C Factor\sout\sbtree\stest\slogic\sinto\sa\sseparate\stest_btree.c\sfile.\s(CVS\s3928)
+D 2007-05-05T18:39:25
+F Makefile.in ea8888bdcf53313d26576fcabcb6d0a10ecd35cd
 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
 F VERSION 6de5e9812c227f00155cb59af3535017aef3e258
@@ -44,7 +44,7 @@ F ext/fts2/fts2_tokenizer1.c 5c979fe8815f95396beb22b627571da895a025af
 F ext/fts2/mkfts2amal.tcl 2a9ec76b0760fe7f3669dca5bc0d60728bc1c977
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
 F ltmain.sh 56abb507100ed2d4261f6dd1653dec3cf4066387
-F main.mk b9fd506a8ff3abd83b01dff9abdb98948a207f26
+F main.mk a7522a769f2fe70c9bebd6bd8a36bed79be0e5cb
 F mkdll.sh ed62756baf44babf562a7843588790c02fee2106
 F mkopcodec.awk bd46ad001c98dfbab07b1713cb8e692fa0e5415d
 F mkopcodeh.awk cde995d269aa06c94adbf6455bea0acedb913fa5
@@ -59,9 +59,9 @@ F src/alter.c 2c79ec40f65e33deaf90ca493422c74586e481a3
 F src/analyze.c 4bbf5ddf9680587c6d4917e02e378b6037be3651
 F src/attach.c f088f8155541ff75542239ec40cf05f3d81390ba
 F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f
-F src/btree.c 7311696faf137cb37421c8e1d0e22e2d3a15de51
+F src/btree.c 6d3db6416c71f678a4dd4719ce6d754ad5927c46
 F src/btree.h a9cd72b05a14f6be22e057daf954ae548d2bcbe4
-F src/btreeInt.h 2de5f19abb59fcc5e87474fe59ef8110cfa0d343
+F src/btreeInt.h cb3c0e9eb842d06079a62cdf3492c90c5db7ba75
 F src/build.c 0dd6f0d0a5d304be91374f4c7228a3e9b00ff7f1
 F src/callback.c 6414ed32d55859d0f65067aa5b88d2da27b3af9e
 F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675
@@ -104,7 +104,7 @@ F src/sqlite3ext.h 7d0d363ea7327e817ef0dfe1b7eee1f171b72890
 F src/sqliteInt.h 3ffe2f9c801575e315451e7d2831c4a90a165aa8
 F src/table.c a8de75bcedf84d4060d804264b067ab3b1a3561d
 F src/tclsqlite.c f3414b2d6bc37e6760b49c9abd3504ff69f4441b
-F src/test1.c 9fb5a4300897c01add79ff8691114e54e5a83ff0
+F src/test1.c 515a91ed7ee95a6fa5b40873aa4f5aa9c858080e
 F src/test2.c 24458b17ab2f3c90cbc1c8446bd7ffe69be62f88
 F src/test3.c 946ea9d1a8c928656e3c70f0a2fcb8e733a15e86
 F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25
@@ -115,6 +115,7 @@ F src/test8.c c3c4aeea4e3d70966306d6eca1b77ce7eee2f059
 F src/test9.c c0f38f7795cc51d37db6c63874d90f40f10d0f0e
 F src/test_async.c 9d326ceda4306bcab252b8f7e8e480ed45d7ccb6
 F src/test_autoext.c 855157d97aa28cf84233847548bfacda21807436
+F src/test_btree.c 893030a3c49ea36e9b15b01f1609727dfb11c81e
 F src/test_hexio.c 32204b5ce281ebc85f789c69c4ec725129e7e7f5
 F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8
 F src/test_md5.c 6c42bc0a3c0b54be34623ff77a0eec32b2fa96e3
@@ -132,7 +133,7 @@ F src/vdbe.h 0025259af1939fb264a545816c69e4b5b8d52691
 F src/vdbeInt.h cb02cbbceddf3b40d49012e9f41576f17bcbec97
 F src/vdbeapi.c 37d793559390bec8a00c556f651f21b5f9e589af
 F src/vdbeaux.c c432e17fef6efaf102d507e979cee4e47f6ceac4
-F src/vdbeblob.c 6a25e9bbb874a7dcee4cf8f37d8dd635c129002e
+F src/vdbeblob.c 57127dc9fd01f3fded2eab30b5842f5f96b1c42b
 F src/vdbefifo.c 3ca8049c561d5d67cbcb94dc909ae9bb68c0bf8f
 F src/vdbemem.c ba98f8572ec4609846b368fa7580db178022f1bb
 F src/vtab.c c5ebebf615b2f29499fbe97a584c4bb342632aa0
@@ -326,7 +327,7 @@ F test/select5.test 0b47058d3e916c1fc9fe81f44b438e02bade21ce
 F test/select6.test 399f14b9ba37b768afe5d2cd8c12e4f340a69db8
 F test/select7.test 95697d8e8355ef7538e2fe768da16838bbd0fcde
 F test/server1.test e328b8e641ba8fe9273132cfef497383185dc1f5
-F test/shared.test 315934fecff5ecb884449eaa5bae9876961f2f22
+F test/shared.test 5c39f216ce85d723eda5875804bbf5ef8a03fcfc
 F test/shared2.test 8b48f8d33494413ef4cf250110d89403e2bf6b23
 F test/shared3.test 01e3e124dbb3859788aabc7cfb82f7ea04421749
 F test/shared_err.test cc528f6e78665787e93d9ce3a782a2ce5179d821
@@ -477,7 +478,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P ad549a40ed3500fb3d552ed19ff791d1280e0b62
-R 8e70c7a5e1bfad9e41e67f958c0c12ec
+P 54a1d275aa0154a88d433a3c4df538d52c2c3ecb
+R b1bb50d4a308744ac562ad6378a81905
 U drh
-Z 58284854439e023cfa44a554bd182ac1
+Z 79b62501eb7362c290096e8263df6144
index 92064bc0d462b8af6c0ac94203cf4bb1daba744d..b6727c4032c4147291967eb51e803d095ba9261d 100644 (file)
@@ -1 +1 @@
-54a1d275aa0154a88d433a3c4df538d52c2c3ecb
\ No newline at end of file
+d51274f1cc3a75f6a03e90259ce829ac1dacf78f
\ No newline at end of file
index 025fbf35dd5f536830b0254173c5da2dce5a8262..97cd84a43e45cd7903087d535d6776fccc2a1188 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.376 2007/05/05 11:48:54 drh Exp $
+** $Id: btree.c,v 1.377 2007/05/05 18:39:25 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** See the header comment on "btreeInt.h" for additional information.
@@ -298,7 +298,7 @@ static void clearCursorPosition(BtCursor *pCur){
 ** returning the cursor to it's saved position, any saved position is deleted
 ** and the cursor state set to CURSOR_INVALID.
 */
-static int restoreOrClearCursorPositionX(BtCursor *pCur){
+int sqlite3BtreeRestoreOrClearCursorPosition(BtCursor *pCur){
   int rc;
   assert( pCur->eState==CURSOR_REQUIRESEEK );
 #ifndef SQLITE_OMIT_INCRBLOB
@@ -317,7 +317,9 @@ static int restoreOrClearCursorPositionX(BtCursor *pCur){
 }
 
 #define restoreOrClearCursorPosition(p) \
-  (p->eState==CURSOR_REQUIRESEEK?restoreOrClearCursorPositionX(p):SQLITE_OK)
+  (p->eState==CURSOR_REQUIRESEEK ? \
+         sqlite3BtreeRestoreOrClearCursorPosition(p) : \
+         SQLITE_OK)
 
 #ifndef SQLITE_OMIT_AUTOVACUUM
 /*
@@ -417,7 +419,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
 **
 ** This routine works only for pages that do not contain overflow cells.
 */
-static u8 *findCell(MemPage *pPage, int iCell){
+u8 *sqlite3BtreeFindCell(MemPage *pPage, int iCell){
   u8 *data = pPage->aData;
   assert( iCell>=0 );
   assert( iCell<get2byte(&data[pPage->hdrOffset+3]) );
@@ -425,7 +427,7 @@ static u8 *findCell(MemPage *pPage, int iCell){
 }
 
 /*
-** This a more complex version of findCell() that works for
+** This a more complex version of sqlite3BtreeFindCell() that works for
 ** pages that do contain overflow cells.  See insert
 */
 static u8 *findOverflowCell(MemPage *pPage, int iCell){
@@ -442,16 +444,16 @@ static u8 *findOverflowCell(MemPage *pPage, int iCell){
       iCell--;
     }
   }
-  return findCell(pPage, iCell);
+  return sqlite3BtreeFindCell(pPage, iCell);
 }
 
 /*
 ** Parse a cell content block and fill in the CellInfo structure.  There
-** are two versions of this function.  parseCell() takes a cell index
-** as the second argument and parseCellPtr() takes a pointer to the
-** body of the cell as its second argument.
+** are two versions of this function.  sqlite3BtreeParseCell() takes a 
+** cell index as the second argument and sqlite3BtreeParseCellPtr() 
+** takes a pointer to the body of the cell as its second argument.
 */
-static void parseCellPtr(
+void sqlite3BtreeParseCellPtr(
   MemPage *pPage,         /* Page containing the cell */
   u8 *pCell,              /* Pointer to the cell text. */
   CellInfo *pInfo         /* Fill in this structure */
@@ -517,12 +519,12 @@ static void parseCellPtr(
     pInfo->nSize = pInfo->iOverflow + 4;
   }
 }
-static void parseCell(
+void sqlite3BtreeParseCell(
   MemPage *pPage,         /* Page containing the cell */
   int iCell,              /* The cell index.  First cell is 0 */
   CellInfo *pInfo         /* Fill in this structure */
 ){
-  parseCellPtr(pPage, findCell(pPage, iCell), pInfo);
+  sqlite3BtreeParseCellPtr(pPage, sqlite3BtreeFindCell(pPage, iCell), pInfo);
 }
 
 /*
@@ -534,13 +536,13 @@ static void parseCell(
 #ifndef NDEBUG
 static int cellSize(MemPage *pPage, int iCell){
   CellInfo info;
-  parseCell(pPage, iCell, &info);
+  sqlite3BtreeParseCell(pPage, iCell, &info);
   return info.nSize;
 }
 #endif
 static int cellSizePtr(MemPage *pPage, u8 *pCell){
   CellInfo info;
-  parseCellPtr(pPage, pCell, &info);
+  sqlite3BtreeParseCellPtr(pPage, pCell, &info);
   return info.nSize;
 }
 
@@ -553,7 +555,7 @@ static int cellSizePtr(MemPage *pPage, u8 *pCell){
 static int ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell){
   if( pCell ){
     CellInfo info;
-    parseCellPtr(pPage, pCell, &info);
+    sqlite3BtreeParseCellPtr(pPage, pCell, &info);
     assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
     if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){
       Pgno ovfl = get4byte(&pCell[info.iOverflow]);
@@ -802,7 +804,7 @@ static void decodeFlags(MemPage *pPage, int flagByte){
 ** guarantee that the page is well-formed.  It only shows that
 ** we failed to detect any corruption.
 */
-static int initPage(
+int sqlite3BtreeInitPage(
   MemPage *pPage,        /* The page to be initialized */
   MemPage *pParent       /* The parent.  Might be NULL */
 ){
@@ -915,7 +917,12 @@ static void zeroPage(MemPage *pPage, int flags){
 ** means we have started to be concerned about content and the disk
 ** read should occur at that point.
 */
-static int getPage(BtShared *pBt, Pgno pgno, MemPage **ppPage, int noContent){
+int sqlite3BtreeGetPage(
+  BtShared *pBt,       /* The btree */
+  Pgno pgno,           /* Number of the page to fetch */
+  MemPage **ppPage,    /* Return the page in this parameter */
+  int noContent        /* Do not load page content if true */
+){
   int rc;
   MemPage *pPage;
   DbPage *pDbPage;
@@ -935,7 +942,7 @@ static int getPage(BtShared *pBt, Pgno pgno, MemPage **ppPage, int noContent){
 /*
 ** Get a page from the pager and initialize it.  This routine
 ** is just a convenience wrapper around separate calls to
-** getPage() and initPage().
+** sqlite3BtreeGetPage() and sqlite3BtreeInitPage().
 */
 static int getAndInitPage(
   BtShared *pBt,          /* The database file */
@@ -947,16 +954,16 @@ static int getAndInitPage(
   if( pgno==0 ){
     return SQLITE_CORRUPT_BKPT; 
   }
-  rc = getPage(pBt, pgno, ppPage, 0);
+  rc = sqlite3BtreeGetPage(pBt, pgno, ppPage, 0);
   if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){
-    rc = initPage(*ppPage, pParent);
+    rc = sqlite3BtreeInitPage(*ppPage, pParent);
   }
   return rc;
 }
 
 /*
 ** Release a MemPage.  This should be called once for each prior
-** call to getPage.
+** call to sqlite3BtreeGetPage.
 */
 static void releasePage(MemPage *pPage){
   if( pPage ){
@@ -998,7 +1005,7 @@ static void pageReinit(DbPage *pData, int pageSize){
   pPage = (MemPage *)sqlite3PagerGetExtra(pData);
   if( pPage->isInit ){
     pPage->isInit = 0;
-    initPage(pPage, pPage->pParent);
+    sqlite3BtreeInitPage(pPage, pPage->pParent);
   }
 }
 
@@ -1379,7 +1386,7 @@ static int lockBtree(BtShared *pBt){
   int rc, pageSize;
   MemPage *pPage1;
   if( pBt->pPage1 ) return SQLITE_OK;
-  rc = getPage(pBt, 1, &pPage1, 0);
+  rc = sqlite3BtreeGetPage(pBt, 1, &pPage1, 0);
   if( rc!=SQLITE_OK ) return rc;
   
 
@@ -1641,11 +1648,11 @@ static int setChildPtrmaps(MemPage *pPage){
   int isInitOrig = pPage->isInit;
   Pgno pgno = pPage->pgno;
 
-  initPage(pPage, 0);
+  sqlite3BtreeInitPage(pPage, 0);
   nCell = pPage->nCell;
 
   for(i=0; i<nCell; i++){
-    u8 *pCell = findCell(pPage, i);
+    u8 *pCell = sqlite3BtreeFindCell(pPage, i);
 
     rc = ptrmapPutOvflPtr(pPage, pCell);
     if( rc!=SQLITE_OK ){
@@ -1696,14 +1703,14 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
     int i;
     int nCell;
 
-    initPage(pPage, 0);
+    sqlite3BtreeInitPage(pPage, 0);
     nCell = pPage->nCell;
 
     for(i=0; i<nCell; i++){
-      u8 *pCell = findCell(pPage, i);
+      u8 *pCell = sqlite3BtreeFindCell(pPage, i);
       if( eType==PTRMAP_OVERFLOW1 ){
         CellInfo info;
-        parseCellPtr(pPage, pCell, &info);
+        sqlite3BtreeParseCellPtr(pPage, pCell, &info);
         if( info.iOverflow ){
           if( iFrom==get4byte(&pCell[info.iOverflow]) ){
             put4byte(&pCell[info.iOverflow], iTo);
@@ -1788,7 +1795,7 @@ static int relocatePage(
   ** iPtrPage.
   */
   if( eType!=PTRMAP_ROOTPAGE ){
-    rc = getPage(pBt, iPtrPage, &pPtrPage, 0);
+    rc = sqlite3BtreeGetPage(pBt, iPtrPage, &pPtrPage, 0);
     if( rc!=SQLITE_OK ){
       return rc;
     }
@@ -1871,7 +1878,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin){
       Pgno iFreePg;             /* Index of free page to move pLastPg to */
       MemPage *pLastPg;
 
-      rc = getPage(pBt, iLastPg, &pLastPg, 0);
+      rc = sqlite3BtreeGetPage(pBt, iLastPg, &pLastPg, 0);
       if( rc!=SQLITE_OK ){
         return rc;
       }
@@ -2132,25 +2139,6 @@ static int countWriteCursors(BtShared *pBt){
 }
 #endif
 
-#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
-/*
-** Print debugging information about all cursors to standard output.
-*/
-void sqlite3BtreeCursorList(Btree *p){
-  BtCursor *pCur;
-  BtShared *pBt = p->pBt;
-  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
-    MemPage *pPage = pCur->pPage;
-    char *zMode = pCur->wrFlag ? "rw" : "ro";
-    sqlite3DebugPrintf("CURSOR %p rooted at %4d(%s) currently at %d.%d%s\n",
-       pCur, pCur->pgnoRoot, zMode,
-       pPage ? pPage->pgno : 0, pCur->idx,
-       (pCur->eState==CURSOR_VALID) ? "" : " eof"
-    );
-  }
-}
-#endif
-
 /*
 ** Rollback the transaction in progress.  All cursors will be
 ** invalided by this operation.  Any attempt to use a cursor
@@ -2200,9 +2188,9 @@ int sqlite3BtreeRollback(Btree *p){
     }
 
     /* The rollback may have destroyed the pPage1->aData value.  So
-    ** call getPage() on page 1 again to make sure pPage1->aData is
-    ** set correctly. */
-    if( getPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
+    ** call sqlite3BtreeGetPage() on page 1 again to make
+    ** sure pPage1->aData is set correctly. */
+    if( sqlite3BtreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
       releasePage(pPage1);
     }
     assert( countWriteCursors(pBt)==0 );
@@ -2452,7 +2440,7 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){
 ** Make a temporary cursor by filling in the fields of pTempCur.
 ** The temporary cursor is not on the cursor list for the Btree.
 */
-static void getTempCursor(BtCursor *pCur, BtCursor *pTempCur){
+void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur){
   memcpy(pTempCur, pCur, sizeof(*pCur));
   pTempCur->pNext = 0;
   pTempCur->pPrev = 0;
@@ -2465,7 +2453,7 @@ static void getTempCursor(BtCursor *pCur, BtCursor *pTempCur){
 ** Delete a temporary cursor such as was made by the CreateTemporaryCursor()
 ** function above.
 */
-static void releaseTempCursor(BtCursor *pCur){
+void sqlite3BtreeReleaseTempCursor(BtCursor *pCur){
   if( pCur->pPage ){
     sqlite3PagerUnref(pCur->pPage->pDbPage);
   }
@@ -2473,19 +2461,19 @@ static void releaseTempCursor(BtCursor *pCur){
 
 /*
 ** Make sure the BtCursor.info field of the given cursor is valid.
-** If it is not already valid, call parseCell() to fill it in.
+** If it is not already valid, call sqlite3BtreeParseCell() to fill it in.
 **
 ** BtCursor.info is a cache of the information in the current cell.
-** Using this cache reduces the number of calls to parseCell().
+** Using this cache reduces the number of calls to sqlite3BtreeParseCell().
 */
 static void getCellInfo(BtCursor *pCur){
   if( pCur->info.nSize==0 ){
-    parseCell(pCur->pPage, pCur->idx, &pCur->info);
+    sqlite3BtreeParseCell(pCur->pPage, pCur->idx, &pCur->info);
   }else{
 #ifndef NDEBUG
     CellInfo info;
     memset(&info, 0, sizeof(info));
-    parseCell(pCur->pPage, pCur->idx, &info);
+    sqlite3BtreeParseCell(pCur->pPage, pCur->idx, &info);
     assert( memcmp(&info, &pCur->info, sizeof(info))==0 );
 #endif
   }
@@ -2568,7 +2556,7 @@ static int getOverflowPage(
   ** a MemPage* reference only. No page-data is required in this case.
   */
   if( !pPgnoNext ){
-    return getPage(pBt, ovfl, ppPage, 1);
+    return sqlite3BtreeGetPage(pBt, ovfl, ppPage, 1);
   }
 
 #ifndef SQLITE_OMIT_AUTOVACUUM
@@ -2602,7 +2590,7 @@ static int getOverflowPage(
   if( next==0 || ppPage ){
     MemPage *pPage = 0;
 
-    rc = getPage(pBt, ovfl, &pPage, next!=0);
+    rc = sqlite3BtreeGetPage(pBt, ovfl, &pPage, next!=0);
     assert(rc==SQLITE_OK || pPage==0);
     if( next==0 && rc==SQLITE_OK ){
       next = get4byte(pPage->aData);
@@ -2681,7 +2669,6 @@ static int copyPayload(
 **   * A commit in auto_vacuum="full" mode,
 **   * Creating a table (may require moving an overflow page).
 */
-#define getPayload(a,b,c,d,e) accessPayload(a,b,c,d,e,0)
 static int accessPayload(
   BtCursor *pCur,      /* Cursor pointing to entry to read from */
   int offset,          /* Begin reading this far into payload */
@@ -2834,7 +2821,7 @@ int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
     }
     assert( pCur->pPage->intKey==0 );
     assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
-    rc = getPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
+    rc = accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0, 0);
   }
   return rc;
 }
@@ -2854,7 +2841,7 @@ int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
     assert( pCur->eState==CURSOR_VALID );
     assert( pCur->pPage!=0 );
     assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
-    rc = getPayload(pCur, offset, amt, pBuf, 1);
+    rc = accessPayload(pCur, offset, amt, pBuf, 1, 0);
   }
   return rc;
 }
@@ -2871,7 +2858,7 @@ int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
 ** and data to fit on the local page and for there to be no overflow
 ** pages.  When that is so, this routine can be used to access the
 ** key and data without making a copy.  If the key and/or data spills
-** onto overflow pages, then getPayload() must be used to reassembly
+** onto overflow pages, then accessPayload() must be used to reassembly
 ** the key/data and copy it into a preallocated buffer.
 **
 ** The pointer returned by this routine looks directly into the cached
@@ -2974,7 +2961,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
 ** virtual root page is the page that the right-pointer of page
 ** 1 is pointing to.
 */
-static int isRootPage(MemPage *pPage){
+int sqlite3BtreeIsRootPage(MemPage *pPage){
   MemPage *pParent = pPage->pParent;
   if( pParent==0 ) return 1;
   if( pParent->pgno>1 ) return 0;
@@ -2990,7 +2977,7 @@ static int isRootPage(MemPage *pPage){
 ** right-most child page then pCur->idx is set to one more than
 ** the largest cell index.
 */
-static void moveToParent(BtCursor *pCur){
+void sqlite3BtreeMoveToParent(BtCursor *pCur){
   MemPage *pParent;
   MemPage *pPage;
   int idxParent;
@@ -2998,7 +2985,7 @@ static void moveToParent(BtCursor *pCur){
   assert( pCur->eState==CURSOR_VALID );
   pPage = pCur->pPage;
   assert( pPage!=0 );
-  assert( !isRootPage(pPage) );
+  assert( !sqlite3BtreeIsRootPage(pPage) );
   pParent = pPage->pParent;
   assert( pParent!=0 );
   idxParent = pPage->idxParent;
@@ -3063,7 +3050,7 @@ static int moveToLeftmost(BtCursor *pCur){
   assert( pCur->eState==CURSOR_VALID );
   while( !(pPage = pCur->pPage)->leaf ){
     assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
-    pgno = get4byte(findCell(pPage, pCur->idx));
+    pgno = get4byte(sqlite3BtreeFindCell(pPage, pCur->idx));
     rc = moveToChild(pCur, pgno);
     if( rc ) return rc;
   }
@@ -3200,7 +3187,7 @@ int sqlite3BtreeMoveto(
       pCur->info.nSize = 0;
       if( pPage->intKey ){
         u8 *pCell;
-        pCell = findCell(pPage, pCur->idx) + pPage->childPtrSize;
+        pCell = sqlite3BtreeFindCell(pPage, pCur->idx) + pPage->childPtrSize;
         if( pPage->hasData ){
           u32 dummy;
           pCell += getVarint32(pCell, &dummy);
@@ -3255,7 +3242,7 @@ int sqlite3BtreeMoveto(
     }else if( lwr>=pPage->nCell ){
       chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
     }else{
-      chldPg = get4byte(findCell(pPage, lwr));
+      chldPg = get4byte(sqlite3BtreeFindCell(pPage, lwr));
     }
     if( chldPg==0 ){
       assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
@@ -3328,12 +3315,12 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
       return rc;
     }
     do{
-      if( isRootPage(pPage) ){
+      if( sqlite3BtreeIsRootPage(pPage) ){
         *pRes = 1;
         pCur->eState = CURSOR_INVALID;
         return SQLITE_OK;
       }
-      moveToParent(pCur);
+      sqlite3BtreeMoveToParent(pCur);
       pPage = pCur->pPage;
     }while( pCur->idx>=pPage->nCell );
     *pRes = 0;
@@ -3382,18 +3369,18 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
   assert( pPage->isInit );
   assert( pCur->idx>=0 );
   if( !pPage->leaf ){
-    pgno = get4byte( findCell(pPage, pCur->idx) );
+    pgno = get4byte( sqlite3BtreeFindCell(pPage, pCur->idx) );
     rc = moveToChild(pCur, pgno);
     if( rc ) return rc;
     rc = moveToRightmost(pCur);
   }else{
     while( pCur->idx==0 ){
-      if( isRootPage(pPage) ){
+      if( sqlite3BtreeIsRootPage(pPage) ){
         pCur->eState = CURSOR_INVALID;
         *pRes = 1;
         return SQLITE_OK;
       }
-      moveToParent(pCur);
+      sqlite3BtreeMoveToParent(pCur);
       pPage = pCur->pPage;
     }
     pCur->idx--;
@@ -3486,7 +3473,7 @@ static int allocateBtreePage(
       }else{
         iTrunk = get4byte(&pPage1->aData[32]);
       }
-      rc = getPage(pBt, iTrunk, &pTrunk, 0);
+      rc = sqlite3BtreeGetPage(pBt, iTrunk, &pTrunk, 0);
       if( rc ){
         pTrunk = 0;
         goto end_allocate_page;
@@ -3536,7 +3523,7 @@ static int allocateBtreePage(
           */
           MemPage *pNewTrunk;
           Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
-          rc = getPage(pBt, iNewTrunk, &pNewTrunk, 0);
+          rc = sqlite3BtreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
           if( rc!=SQLITE_OK ){
             goto end_allocate_page;
           }
@@ -3602,7 +3589,7 @@ static int allocateBtreePage(
             memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
           }
           put4byte(&aData[4], k-1);
-          rc = getPage(pBt, *pPgno, ppPage, 1);
+          rc = sqlite3BtreeGetPage(pBt, *pPgno, ppPage, 1);
           if( rc==SQLITE_OK ){
             sqlite3PagerDontRollback((*ppPage)->pDbPage);
             rc = sqlite3PagerWrite((*ppPage)->pDbPage);
@@ -3647,7 +3634,7 @@ static int allocateBtreePage(
 #endif
 
     assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
-    rc = getPage(pBt, *pPgno, ppPage, 0);
+    rc = sqlite3BtreeGetPage(pBt, *pPgno, ppPage, 0);
     if( rc ) return rc;
     rc = sqlite3PagerWrite((*ppPage)->pDbPage);
     if( rc!=SQLITE_OK ){
@@ -3716,7 +3703,7 @@ static int freePage(MemPage *pPage){
     /* Other free pages already exist.  Retrive the first trunk page
     ** of the freelist and find out how many leaves it has. */
     MemPage *pTrunk;
-    rc = getPage(pBt, get4byte(&pPage1->aData[32]), &pTrunk, 0);
+    rc = sqlite3BtreeGetPage(pBt, get4byte(&pPage1->aData[32]), &pTrunk, 0);
     if( rc ) return rc;
     k = get4byte(&pTrunk->aData[4]);
     if( k>=pBt->usableSize/4 - 8 ){
@@ -3757,7 +3744,7 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){
   int nOvfl;
   int ovflPageSize;
 
-  parseCellPtr(pPage, pCell, &info);
+  sqlite3BtreeParseCellPtr(pPage, pCell, &info);
   if( info.iOverflow==0 ){
     return SQLITE_OK;  /* No overflow pages. Return without doing anything */
   }
@@ -3824,7 +3811,7 @@ static int fillInCell(
     nData = nZero = 0;
   }
   nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey);
-  parseCellPtr(pPage, pCell, &info);
+  sqlite3BtreeParseCellPtr(pPage, pCell, &info);
   assert( info.nHeader==nHeader );
   assert( info.nKey==nKey );
   assert( info.nData==nData+nZero );
@@ -3951,7 +3938,7 @@ static int reparentChildPages(MemPage *pPage){
   if( pPage->leaf ) return SQLITE_OK;
 
   for(i=0; i<pPage->nCell; i++){
-    u8 *pCell = findCell(pPage, i);
+    u8 *pCell = sqlite3BtreeFindCell(pPage, i);
     if( !pPage->leaf ){
       rc = reparentPage(pBt, get4byte(pCell), pPage, i);
       if( rc!=SQLITE_OK ) return rc;
@@ -4077,7 +4064,7 @@ static int insertCell(
       ** the entry for the overflow page into the pointer map.
       */
       CellInfo info;
-      parseCellPtr(pPage, pCell, &info);
+      sqlite3BtreeParseCellPtr(pPage, pCell, &info);
       assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
       if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){
         Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
@@ -4205,7 +4192,8 @@ static int balance_quick(MemPage *pPage, MemPage *pParent){
   ** pPage is the next-to-right child. 
   */
   assert( pPage->nCell>0 );
-  parseCellPtr(pPage, findCell(pPage, pPage->nCell-1), &info);
+  pCell = sqlite3BtreeFindCell(pPage, pPage->nCell-1);
+  sqlite3BtreeParseCellPtr(pPage, pCell, &info);
   rc = fillInCell(pParent, parentCell, 0, info.nKey, 0, 0, 0, &parentSize);
   if( rc!=SQLITE_OK ){
     return rc;
@@ -4274,7 +4262,7 @@ static int balance_quick(MemPage *pPage, MemPage *pParent){
 */
 static int balance_nonroot(MemPage *pPage){
   MemPage *pParent;            /* The parent of pPage */
-  BtShared *pBt;                  /* The whole database */
+  BtShared *pBt;               /* The whole database */
   int nCell = 0;               /* Number of cells in apCell[] */
   int nMaxCells = 0;           /* Allocated size of apCell, szCell, aFrom. */
   int nOld;                    /* Number of pages in apOld[] */
@@ -4354,7 +4342,7 @@ static int balance_nonroot(MemPage *pPage){
     pgno = pPage->pgno;
     assert( pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
     for(idx=0; idx<pParent->nCell; idx++){
-      if( get4byte(findCell(pParent, idx))==pgno ){
+      if( get4byte(sqlite3BtreeFindCell(pParent, idx))==pgno ){
         break;
       }
     }
@@ -4388,7 +4376,7 @@ static int balance_nonroot(MemPage *pPage){
   nDiv = 0;
   for(i=0, k=nxDiv; i<NB; i++, k++){
     if( k<pParent->nCell ){
-      apDiv[i] = findCell(pParent, k);
+      apDiv[i] = sqlite3BtreeFindCell(pParent, k);
       nDiv++;
       assert( !pParent->leaf );
       pgnoOld[i] = get4byte(apDiv[i]);
@@ -4737,7 +4725,7 @@ static int balance_nonroot(MemPage *pPage){
         */
         CellInfo info;
         j--;
-        parseCellPtr(pNew, apCell[j], &info);
+        sqlite3BtreeParseCellPtr(pNew, apCell[j], &info);
         pCell = &aSpace[iSpace];
         fillInCell(pParent, pCell, 0, info.nKey, 0, 0, 0, &sz);
         iSpace += sz;
@@ -4858,10 +4846,10 @@ static int balance_shallower(MemPage *pPage){
     pgnoChild = get4byte(&pPage->aData[pPage->hdrOffset+8]);
     assert( pgnoChild>0 );
     assert( pgnoChild<=sqlite3PagerPagecount(pPage->pBt->pPager) );
-    rc = getPage(pPage->pBt, pgnoChild, &pChild, 0);
+    rc = sqlite3BtreeGetPage(pPage->pBt, pgnoChild, &pChild, 0);
     if( rc ) goto end_shallow_balance;
     if( pPage->pgno==1 ){
-      rc = initPage(pChild, pPage);
+      rc = sqlite3BtreeInitPage(pChild, pPage);
       if( rc ) goto end_shallow_balance;
       assert( pChild->nOverflow==0 );
       if( pChild->nFree>=100 ){
@@ -4870,7 +4858,7 @@ static int balance_shallower(MemPage *pPage){
         int i;
         zeroPage(pPage, pChild->aData[0]);
         for(i=0; i<pChild->nCell; i++){
-          apCell[i] = findCell(pChild,i);
+          apCell[i] = sqlite3BtreeFindCell(pChild,i);
           szCell[i] = cellSizePtr(pChild, apCell[i]);
         }
         assemblePage(pPage, pChild->nCell, apCell, szCell);
@@ -4888,7 +4876,7 @@ static int balance_shallower(MemPage *pPage){
       memcpy(pPage->aData, pChild->aData, pPage->pBt->usableSize);
       pPage->isInit = 0;
       pPage->pParent = 0;
-      rc = initPage(pPage, 0);
+      rc = sqlite3BtreeInitPage(pPage, 0);
       assert( rc==SQLITE_OK );
       freePage(pChild);
       TRACE(("BALANCE: transfer child %d into root %d\n",
@@ -4950,7 +4938,7 @@ static int balance_deeper(MemPage *pPage){
   memcpy(cdata, &data[hdr], pPage->cellOffset+2*pPage->nCell-hdr);
   memcpy(&cdata[brk], &data[brk], usableSize-brk);
   assert( pChild->isInit==0 );
-  rc = initPage(pChild, pPage);
+  rc = sqlite3BtreeInitPage(pChild, pPage);
   if( rc ) goto balancedeeper_out;
   memcpy(pChild->aOvfl, pPage->aOvfl, pPage->nOverflow*sizeof(pPage->aOvfl[0]));
   pChild->nOverflow = pPage->nOverflow;
@@ -5013,7 +5001,7 @@ static int balance(MemPage *pPage, int insert){
 **
 ** In addition to checking for read-locks (where a read-lock 
 ** means a cursor opened with wrFlag==0) this routine also moves
-** all cursors write cursors so that they are pointing to the 
+** all write cursors so that they are pointing to the 
 ** first Cell on the root page.  This is necessary because an insert 
 ** or delete might change the number of cells on a page or delete
 ** a page entirely and we do not want to leave any cursors 
@@ -5103,7 +5091,7 @@ int sqlite3BtreeInsert(
   if( loc==0 && CURSOR_VALID==pCur->eState ){
     int szOld;
     assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
-    oldCell = findCell(pPage, pCur->idx);
+    oldCell = sqlite3BtreeFindCell(pPage, pCur->idx);
     if( !pPage->leaf ){
       memcpy(newCell, oldCell, 4);
     }
@@ -5175,7 +5163,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){
   ** data. The clearCell() call frees any overflow pages associated with the
   ** cell. The cell itself is still intact.
   */
-  pCell = findCell(pPage, pCur->idx);
+  pCell = sqlite3BtreeFindCell(pPage, pCur->idx);
   if( !pPage->leaf ){
     pgnoChild = get4byte(pCell);
   }
@@ -5198,7 +5186,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){
     int notUsed;
     unsigned char *tempCell = 0;
     assert( !pPage->leafData );
-    getTempCursor(pCur, &leafCur);
+    sqlite3BtreeGetTempCursor(pCur, &leafCur);
     rc = sqlite3BtreeNext(&leafCur, &notUsed);
     if( rc==SQLITE_OK ){
       rc = sqlite3PagerWrite(leafCur.pPage->pDbPage);
@@ -5207,7 +5195,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){
       TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n",
          pCur->pgnoRoot, pPage->pgno, leafCur.pPage->pgno));
       dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell));
-      pNext = findCell(leafCur.pPage, leafCur.idx);
+      pNext = sqlite3BtreeFindCell(leafCur.pPage, leafCur.idx);
       szNext = cellSizePtr(leafCur.pPage, pNext);
       assert( MX_CELL_SIZE(pBt)>=szNext+4 );
       tempCell = sqliteMallocRaw( MX_CELL_SIZE(pBt) );
@@ -5227,7 +5215,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){
       rc = balance(leafCur.pPage, 0);
     }
     sqliteFree(tempCell);
-    releaseTempCursor(&leafCur);
+    sqlite3BtreeReleaseTempCursor(&leafCur);
   }else{
     TRACE(("DELETE: table=%d delete from leaf %d\n",
        pCur->pgnoRoot, pPage->pgno));
@@ -5316,7 +5304,7 @@ int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){
       releasePage(pPageMove);
 
       /* Move the page currently at pgnoRoot to pgnoMove. */
-      rc = getPage(pBt, pgnoRoot, &pRoot, 0);
+      rc = sqlite3BtreeGetPage(pBt, pgnoRoot, &pRoot, 0);
       if( rc!=SQLITE_OK ){
         return rc;
       }
@@ -5339,7 +5327,7 @@ int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){
       if( rc!=SQLITE_OK ){
         return rc;
       }
-      rc = getPage(pBt, pgnoRoot, &pRoot, 0);
+      rc = sqlite3BtreeGetPage(pBt, pgnoRoot, &pRoot, 0);
       if( rc!=SQLITE_OK ){
         return rc;
       }
@@ -5398,7 +5386,7 @@ static int clearDatabasePage(
   rc = getAndInitPage(pBt, pgno, &pPage, pParent);
   if( rc ) goto cleardatabasepage_out;
   for(i=0; i<pPage->nCell; i++){
-    pCell = findCell(pPage, i);
+    pCell = sqlite3BtreeFindCell(pPage, i);
     if( !pPage->leaf ){
       rc = clearDatabasePage(pBt, get4byte(pCell), pPage->pParent, 1);
       if( rc ) goto cleardatabasepage_out;
@@ -5488,7 +5476,7 @@ int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
     return SQLITE_LOCKED;
   }
 
-  rc = getPage(pBt, (Pgno)iTable, &pPage, 0);
+  rc = sqlite3BtreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
   if( rc ) return rc;
   rc = sqlite3BtreeClearTable(p, iTable);
   if( rc ){
@@ -5527,7 +5515,7 @@ int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
         */
         MemPage *pMove;
         releasePage(pPage);
-        rc = getPage(pBt, maxRootPgno, &pMove, 0);
+        rc = sqlite3BtreeGetPage(pBt, maxRootPgno, &pMove, 0);
         if( rc!=SQLITE_OK ){
           return rc;
         }
@@ -5536,7 +5524,7 @@ int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
         if( rc!=SQLITE_OK ){
           return rc;
         }
-        rc = getPage(pBt, maxRootPgno, &pMove, 0);
+        rc = sqlite3BtreeGetPage(pBt, maxRootPgno, &pMove, 0);
         if( rc!=SQLITE_OK ){
           return rc;
         }
@@ -5654,185 +5642,6 @@ int sqlite3BtreeFlags(BtCursor *pCur){
   return pPage ? pPage->aData[pPage->hdrOffset] : 0;
 }
 
-#ifdef SQLITE_DEBUG
-/*
-** Print a disassembly of the given page on standard output.  This routine
-** is used for debugging and testing only.
-*/
-static int btreePageDump(BtShared *pBt, int pgno, int recursive, MemPage *pParent){
-  int rc;
-  MemPage *pPage;
-  int i, j, c;
-  int nFree;
-  u16 idx;
-  int hdr;
-  int nCell;
-  int isInit;
-  unsigned char *data;
-  char range[20];
-  unsigned char payload[20];
-
-  rc = getPage(pBt, (Pgno)pgno, &pPage, 0);
-  isInit = pPage->isInit;
-  if( pPage->isInit==0 ){
-    initPage(pPage, pParent);
-  }
-  if( rc ){
-    return rc;
-  }
-  hdr = pPage->hdrOffset;
-  data = pPage->aData;
-  c = data[hdr];
-  pPage->intKey = (c & (PTF_INTKEY|PTF_LEAFDATA))!=0;
-  pPage->zeroData = (c & PTF_ZERODATA)!=0;
-  pPage->leafData = (c & PTF_LEAFDATA)!=0;
-  pPage->leaf = (c & PTF_LEAF)!=0;
-  pPage->hasData = !(pPage->zeroData || (!pPage->leaf && pPage->leafData));
-  nCell = get2byte(&data[hdr+3]);
-  sqlite3DebugPrintf("PAGE %d:  flags=0x%02x  frag=%d   parent=%d\n", pgno,
-    data[hdr], data[hdr+7], 
-    (pPage->isInit && pPage->pParent) ? pPage->pParent->pgno : 0);
-  assert( hdr == (pgno==1 ? 100 : 0) );
-  idx = hdr + 12 - pPage->leaf*4;
-  for(i=0; i<nCell; i++){
-    CellInfo info;
-    Pgno child;
-    unsigned char *pCell;
-    int sz;
-    int addr;
-
-    addr = get2byte(&data[idx + 2*i]);
-    pCell = &data[addr];
-    parseCellPtr(pPage, pCell, &info);
-    sz = info.nSize;
-    sqlite3_snprintf(sizeof(range),range,"%d..%d", addr, addr+sz-1);
-    if( pPage->leaf ){
-      child = 0;
-    }else{
-      child = get4byte(pCell);
-    }
-    sz = info.nData;
-    if( !pPage->intKey ) sz += info.nKey;
-    if( sz>sizeof(payload)-1 ) sz = sizeof(payload)-1;
-    memcpy(payload, &pCell[info.nHeader], sz);
-    for(j=0; j<sz; j++){
-      if( payload[j]<0x20 || payload[j]>0x7f ) payload[j] = '.';
-    }
-    payload[sz] = 0;
-    sqlite3DebugPrintf(
-      "cell %2d: i=%-10s chld=%-4d nk=%-4lld nd=%-4d payload=%s\n",
-      i, range, child, info.nKey, info.nData, payload
-    );
-  }
-  if( !pPage->leaf ){
-    sqlite3DebugPrintf("right_child: %d\n", get4byte(&data[hdr+8]));
-  }
-  nFree = 0;
-  i = 0;
-  idx = get2byte(&data[hdr+1]);
-  while( idx>0 && idx<pPage->pBt->usableSize ){
-    int sz = get2byte(&data[idx+2]);
-    sqlite3_snprintf(sizeof(range),range,"%d..%d", idx, idx+sz-1);
-    nFree += sz;
-    sqlite3DebugPrintf("freeblock %2d: i=%-10s size=%-4d total=%d\n",
-       i, range, sz, nFree);
-    idx = get2byte(&data[idx]);
-    i++;
-  }
-  if( idx!=0 ){
-    sqlite3DebugPrintf("ERROR: next freeblock index out of range: %d\n", idx);
-  }
-  if( recursive && !pPage->leaf ){
-    for(i=0; i<nCell; i++){
-      unsigned char *pCell = findCell(pPage, i);
-      btreePageDump(pBt, get4byte(pCell), 1, pPage);
-      idx = get2byte(pCell);
-    }
-    btreePageDump(pBt, get4byte(&data[hdr+8]), 1, pPage);
-  }
-  pPage->isInit = isInit;
-  sqlite3PagerUnref(pPage->pDbPage);
-  fflush(stdout);
-  return SQLITE_OK;
-}
-int sqlite3BtreePageDump(Btree *p, int pgno, int recursive){
-  return btreePageDump(p->pBt, pgno, recursive, 0);
-}
-#endif
-
-#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
-/*
-** Fill aResult[] with information about the entry and page that the
-** cursor is pointing to.
-** 
-**   aResult[0] =  The page number
-**   aResult[1] =  The entry number
-**   aResult[2] =  Total number of entries on this page
-**   aResult[3] =  Cell size (local payload + header)
-**   aResult[4] =  Number of free bytes on this page
-**   aResult[5] =  Number of free blocks on the page
-**   aResult[6] =  Total payload size (local + overflow)
-**   aResult[7] =  Header size in bytes
-**   aResult[8] =  Local payload size
-**   aResult[9] =  Parent page number
-**   aResult[10]=  Page number of the first overflow page
-**
-** This routine is used for testing and debugging only.
-*/
-int sqlite3BtreeCursorInfo(BtCursor *pCur, int *aResult, int upCnt){
-  int cnt, idx;
-  MemPage *pPage = pCur->pPage;
-  BtCursor tmpCur;
-
-  int rc = restoreOrClearCursorPosition(pCur);
-  if( rc!=SQLITE_OK ){
-    return rc;
-  }
-
-  assert( pPage->isInit );
-  getTempCursor(pCur, &tmpCur);
-  while( upCnt-- ){
-    moveToParent(&tmpCur);
-  }
-  pPage = tmpCur.pPage;
-  aResult[0] = sqlite3PagerPagenumber(pPage->pDbPage);
-  assert( aResult[0]==pPage->pgno );
-  aResult[1] = tmpCur.idx;
-  aResult[2] = pPage->nCell;
-  if( tmpCur.idx>=0 && tmpCur.idx<pPage->nCell ){
-    getCellInfo(&tmpCur);
-    aResult[3] = tmpCur.info.nSize;
-    aResult[6] = tmpCur.info.nData;
-    aResult[7] = tmpCur.info.nHeader;
-    aResult[8] = tmpCur.info.nLocal;
-  }else{
-    aResult[3] = 0;
-    aResult[6] = 0;
-    aResult[7] = 0;
-    aResult[8] = 0;
-  }
-  aResult[4] = pPage->nFree;
-  cnt = 0;
-  idx = get2byte(&pPage->aData[pPage->hdrOffset+1]);
-  while( idx>0 && idx<pPage->pBt->usableSize ){
-    cnt++;
-    idx = get2byte(&pPage->aData[idx]);
-  }
-  aResult[5] = cnt;
-  if( pPage->pParent==0 || isRootPage(pPage) ){
-    aResult[9] = 0;
-  }else{
-    aResult[9] = pPage->pParent->pgno;
-  }
-  if( tmpCur.info.iOverflow ){
-    aResult[10] = get4byte(&tmpCur.info.pCell[tmpCur.info.iOverflow]);
-  }else{
-    aResult[10] = 0;
-  }
-  releaseTempCursor(&tmpCur);
-  return SQLITE_OK;
-}
-#endif
 
 /*
 ** Return the pager associated with a BTree.  This routine is used for
@@ -6040,13 +5849,14 @@ static int checkTreePage(
   usableSize = pBt->usableSize;
   if( iPage==0 ) return 0;
   if( checkRef(pCheck, iPage, zParentContext) ) return 0;
-  if( (rc = getPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
+  if( (rc = sqlite3BtreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
     checkAppendMsg(pCheck, zContext,
        "unable to get the page. error code=%d", rc);
     return 0;
   }
-  if( (rc = initPage(pPage, pParent))!=0 ){
-    checkAppendMsg(pCheck, zContext, "initPage() returns error code %d", rc);
+  if( (rc = sqlite3BtreeInitPage(pPage, pParent))!=0 ){
+    checkAppendMsg(pCheck, zContext, 
+                   "sqlite3BtreeInitPage() returns error code %d", rc);
     releasePage(pPage);
     return 0;
   }
@@ -6063,8 +5873,8 @@ static int checkTreePage(
     */
     sqlite3_snprintf(sizeof(zContext), zContext,
              "On tree page %d cell %d: ", iPage, i);
-    pCell = findCell(pPage,i);
-    parseCellPtr(pPage, pCell, &info);
+    pCell = sqlite3BtreeFindCell(pPage,i);
+    sqlite3BtreeParseCellPtr(pPage, pCell, &info);
     sz = info.nData;
     if( !pPage->intKey ) sz += info.nKey;
     assert( sz==info.nPayload );
@@ -6485,33 +6295,3 @@ void sqlite3BtreeCacheOverflow(BtCursor *pCur){
   pCur->isIncrblobHandle = 1;
 }
 #endif
-
-/*
-** The following debugging interface has to be in this file (rather
-** than in, for example, test1.c) so that it can get access to
-** the definition of BtShared.
-*/
-#if defined(SQLITE_DEBUG) && defined(TCLSH)
-#include <tcl.h>
-int sqlite3_shared_cache_report(
-  void * clientData,
-  Tcl_Interp *interp,
-  int objc,
-  Tcl_Obj *CONST objv[]
-){
-#ifndef SQLITE_OMIT_SHARED_CACHE
-  const ThreadData *pTd = sqlite3ThreadDataReadOnly();
-  if( pTd->useSharedData ){
-    BtShared *pBt;
-    Tcl_Obj *pRet = Tcl_NewObj();
-    for(pBt=pTd->pBtree; pBt; pBt=pBt->pNext){
-      const char *zFile = sqlite3PagerFilename(pBt->pPager);
-      Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(zFile, -1));
-      Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(pBt->nRef));
-    }
-    Tcl_SetObjResult(interp, pRet);
-  }
-#endif
-  return TCL_OK;
-}
-#endif
index 90c8a872ea5da8372ace09e697474f20606e376b..84f823d88caa7b3eb0794650289d6a9fe41d3c92 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btreeInt.h,v 1.1 2007/05/05 11:48:54 drh Exp $
+** $Id: btreeInt.h,v 1.2 2007/05/05 18:39:25 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
@@ -574,3 +574,17 @@ struct IntegrityCk {
 #define get4byte sqlite3Get4byte
 #define put2byte sqlite3Put2byte
 #define put4byte sqlite3Put4byte
+
+/*
+** Internal routines that should be accessed by the btree layer only.
+*/
+int sqlite3BtreeGetPage(BtShared*, Pgno, MemPage**, int);
+int sqlite3BtreeInitPage(MemPage *pPage, MemPage *pParent);
+void sqlite3BtreeParseCellPtr(MemPage*, u8*, CellInfo*);
+void sqlite3BtreeParseCell(MemPage*, int, CellInfo*);
+u8 *sqlite3BtreeFindCell(MemPage *pPage, int iCell);
+int sqlite3BtreeRestoreOrClearCursorPosition(BtCursor *pCur);
+void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur);
+void sqlite3BtreeReleaseTempCursor(BtCursor *pCur);
+int sqlite3BtreeIsRootPage(MemPage *pPage);
+void sqlite3BtreeMoveToParent(BtCursor *pCur);
index bb303ee9df06d1a851ada53224c2d284fce56499..f7db1e598768c8d31f6c4c4a93897f9dabbc2028 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test1.c,v 1.245 2007/05/05 11:48:54 drh Exp $
+** $Id: test1.c,v 1.246 2007/05/05 18:39:25 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -1410,6 +1410,8 @@ static int test_enable_shared(
 }
 #endif
 
+
+
 /*
 ** Usage: sqlite3_extended_result_codes   DB    BOOLEAN
 **
@@ -4486,6 +4488,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
   extern int sqlite3_sort_count;
   extern int sqlite3_current_time;
   extern int sqlite3_max_blobsize;
+  extern int sqlite3BtreeSharedCacheReport(void*,
+                                          Tcl_Interp*,int,Tcl_Obj*CONST*);
   static struct {
      char *zName;
      Tcl_CmdProc *xProc;
@@ -4632,6 +4636,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
      { "tcl_variable_type",       tcl_variable_type, 0       },
 #ifndef SQLITE_OMIT_SHARED_CACHE
      { "sqlite3_enable_shared_cache", test_enable_shared, 0  },
+     { "sqlite3_shared_cache_report", sqlite3BtreeSharedCacheReport, 0},
 #endif
      { "sqlite3_libversion_number", test_libversion_number, 0  },
 #ifdef SQLITE_ENABLE_COLUMN_METADATA
@@ -4763,13 +4768,5 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
 #endif /* OS_UNIX */
   set_options(interp);
 
-  {
-#ifdef SQLITE_DEBUG
-    extern int sqlite3_shared_cache_report(void *, Tcl_Interp *,
-                                    int, Tcl_Obj *CONST[]);
-    Tcl_CreateObjCommand(interp, "sqlite_shared_cache_report", 
-        sqlite3_shared_cache_report, 0, 0);
-#endif
-  }
   return TCL_OK;
 }
diff --git a/src/test_btree.c b/src/test_btree.c
new file mode 100644 (file)
index 0000000..b1de027
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+** 2007 May 05
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+*************************************************************************
+** Code for testing the btree.c module in SQLite.  This code
+** is not included in the SQLite library.  It is used for automated
+** testing of the SQLite library.
+**
+** $Id: test_btree.c,v 1.1 2007/05/05 18:39:25 drh Exp $
+*/
+#include "btreeInt.h"
+#include <tcl.h>
+
+/*
+** Print a disassembly of the given page on standard output.  This routine
+** is used for debugging and testing only.
+*/
+static int btreePageDump(
+  BtShared *pBt,         /* The Btree to be dumped */
+  int pgno,              /* The page to be dumped */
+  int recursive,         /* True to decend into child pages */
+  MemPage *pParent       /* Parent page */
+){
+  int rc;
+  MemPage *pPage;
+  int i, j, c;
+  int nFree;
+  u16 idx;
+  int hdr;
+  int nCell;
+  int isInit;
+  unsigned char *data;
+  char range[20];
+  unsigned char payload[20];
+
+  rc = sqlite3BtreeGetPage(pBt, (Pgno)pgno, &pPage, 0);
+  isInit = pPage->isInit;
+  if( pPage->isInit==0 ){
+    sqlite3BtreeInitPage(pPage, pParent);
+  }
+  if( rc ){
+    return rc;
+  }
+  hdr = pPage->hdrOffset;
+  data = pPage->aData;
+  c = data[hdr];
+  pPage->intKey = (c & (PTF_INTKEY|PTF_LEAFDATA))!=0;
+  pPage->zeroData = (c & PTF_ZERODATA)!=0;
+  pPage->leafData = (c & PTF_LEAFDATA)!=0;
+  pPage->leaf = (c & PTF_LEAF)!=0;
+  pPage->hasData = !(pPage->zeroData || (!pPage->leaf && pPage->leafData));
+  nCell = get2byte(&data[hdr+3]);
+  sqlite3DebugPrintf("PAGE %d:  flags=0x%02x  frag=%d   parent=%d\n", pgno,
+    data[hdr], data[hdr+7], 
+    (pPage->isInit && pPage->pParent) ? pPage->pParent->pgno : 0);
+  assert( hdr == (pgno==1 ? 100 : 0) );
+  idx = hdr + 12 - pPage->leaf*4;
+  for(i=0; i<nCell; i++){
+    CellInfo info;
+    Pgno child;
+    unsigned char *pCell;
+    int sz;
+    int addr;
+
+    addr = get2byte(&data[idx + 2*i]);
+    pCell = &data[addr];
+    sqlite3BtreeParseCellPtr(pPage, pCell, &info);
+    sz = info.nSize;
+    sqlite3_snprintf(sizeof(range),range,"%d..%d", addr, addr+sz-1);
+    if( pPage->leaf ){
+      child = 0;
+    }else{
+      child = get4byte(pCell);
+    }
+    sz = info.nData;
+    if( !pPage->intKey ) sz += info.nKey;
+    if( sz>sizeof(payload)-1 ) sz = sizeof(payload)-1;
+    memcpy(payload, &pCell[info.nHeader], sz);
+    for(j=0; j<sz; j++){
+      if( payload[j]<0x20 || payload[j]>0x7f ) payload[j] = '.';
+    }
+    payload[sz] = 0;
+    sqlite3DebugPrintf(
+      "cell %2d: i=%-10s chld=%-4d nk=%-4lld nd=%-4d payload=%s\n",
+      i, range, child, info.nKey, info.nData, payload
+    );
+  }
+  if( !pPage->leaf ){
+    sqlite3DebugPrintf("right_child: %d\n", get4byte(&data[hdr+8]));
+  }
+  nFree = 0;
+  i = 0;
+  idx = get2byte(&data[hdr+1]);
+  while( idx>0 && idx<pPage->pBt->usableSize ){
+    int sz = get2byte(&data[idx+2]);
+    sqlite3_snprintf(sizeof(range),range,"%d..%d", idx, idx+sz-1);
+    nFree += sz;
+    sqlite3DebugPrintf("freeblock %2d: i=%-10s size=%-4d total=%d\n",
+       i, range, sz, nFree);
+    idx = get2byte(&data[idx]);
+    i++;
+  }
+  if( idx!=0 ){
+    sqlite3DebugPrintf("ERROR: next freeblock index out of range: %d\n", idx);
+  }
+  if( recursive && !pPage->leaf ){
+    for(i=0; i<nCell; i++){
+      unsigned char *pCell = sqlite3BtreeFindCell(pPage, i);
+      btreePageDump(pBt, get4byte(pCell), 1, pPage);
+      idx = get2byte(pCell);
+    }
+    btreePageDump(pBt, get4byte(&data[hdr+8]), 1, pPage);
+  }
+  pPage->isInit = isInit;
+  sqlite3PagerUnref(pPage->pDbPage);
+  fflush(stdout);
+  return SQLITE_OK;
+}
+int sqlite3BtreePageDump(Btree *p, int pgno, int recursive){
+  return btreePageDump(p->pBt, pgno, recursive, 0);
+}
+
+/*
+** Usage: sqlite3_shared_cache_report
+**
+** Return a list of file that are shared and the number of
+** references to each file.
+*/
+int sqlite3BtreeSharedCacheReport(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+#ifndef SQLITE_OMIT_SHARED_CACHE
+  const ThreadData *pTd = sqlite3ThreadDataReadOnly();
+  if( pTd->useSharedData ){
+    BtShared *pBt;
+    Tcl_Obj *pRet = Tcl_NewObj();
+    for(pBt=pTd->pBtree; pBt; pBt=pBt->pNext){
+      const char *zFile = sqlite3PagerFilename(pBt->pPager);
+      Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(zFile, -1));
+      Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(pBt->nRef));
+    }
+    Tcl_SetObjResult(interp, pRet);
+  }
+#endif
+  return TCL_OK;
+}
+
+/*
+** Print debugging information about all cursors to standard output.
+*/
+void sqlite3BtreeCursorList(Btree *p){
+  BtCursor *pCur;
+  BtShared *pBt = p->pBt;
+  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
+    MemPage *pPage = pCur->pPage;
+    char *zMode = pCur->wrFlag ? "rw" : "ro";
+    sqlite3DebugPrintf("CURSOR %p rooted at %4d(%s) currently at %d.%d%s\n",
+       pCur, pCur->pgnoRoot, zMode,
+       pPage ? pPage->pgno : 0, pCur->idx,
+       (pCur->eState==CURSOR_VALID) ? "" : " eof"
+    );
+  }
+}
+
+
+/*
+** Fill aResult[] with information about the entry and page that the
+** cursor is pointing to.
+** 
+**   aResult[0] =  The page number
+**   aResult[1] =  The entry number
+**   aResult[2] =  Total number of entries on this page
+**   aResult[3] =  Cell size (local payload + header)
+**   aResult[4] =  Number of free bytes on this page
+**   aResult[5] =  Number of free blocks on the page
+**   aResult[6] =  Total payload size (local + overflow)
+**   aResult[7] =  Header size in bytes
+**   aResult[8] =  Local payload size
+**   aResult[9] =  Parent page number
+**   aResult[10]=  Page number of the first overflow page
+**
+** This routine is used for testing and debugging only.
+*/
+int sqlite3BtreeCursorInfo(BtCursor *pCur, int *aResult, int upCnt){
+  int cnt, idx;
+  MemPage *pPage = pCur->pPage;
+  BtCursor tmpCur;
+
+  int rc = sqlite3BtreeRestoreOrClearCursorPosition(pCur);
+  if( rc!=SQLITE_OK ){
+    return rc;
+  }
+
+  assert( pPage->isInit );
+  sqlite3BtreeGetTempCursor(pCur, &tmpCur);
+  while( upCnt-- ){
+    sqlite3BtreeMoveToParent(&tmpCur);
+  }
+  pPage = tmpCur.pPage;
+  aResult[0] = sqlite3PagerPagenumber(pPage->pDbPage);
+  assert( aResult[0]==pPage->pgno );
+  aResult[1] = tmpCur.idx;
+  aResult[2] = pPage->nCell;
+  if( tmpCur.idx>=0 && tmpCur.idx<pPage->nCell ){
+    sqlite3BtreeParseCell(tmpCur.pPage, tmpCur.idx, &tmpCur.info);
+    aResult[3] = tmpCur.info.nSize;
+    aResult[6] = tmpCur.info.nData;
+    aResult[7] = tmpCur.info.nHeader;
+    aResult[8] = tmpCur.info.nLocal;
+  }else{
+    aResult[3] = 0;
+    aResult[6] = 0;
+    aResult[7] = 0;
+    aResult[8] = 0;
+  }
+  aResult[4] = pPage->nFree;
+  cnt = 0;
+  idx = get2byte(&pPage->aData[pPage->hdrOffset+1]);
+  while( idx>0 && idx<pPage->pBt->usableSize ){
+    cnt++;
+    idx = get2byte(&pPage->aData[idx]);
+  }
+  aResult[5] = cnt;
+  if( pPage->pParent==0 || sqlite3BtreeIsRootPage(pPage) ){
+    aResult[9] = 0;
+  }else{
+    aResult[9] = pPage->pParent->pgno;
+  }
+  if( tmpCur.info.iOverflow ){
+    aResult[10] = get4byte(&tmpCur.info.pCell[tmpCur.info.iOverflow]);
+  }else{
+    aResult[10] = 0;
+  }
+  sqlite3BtreeReleaseTempCursor(&tmpCur);
+  return SQLITE_OK;
+}
index 8624180602b4cab5420e0f87eca87cb9d22e2489..8f52ca08d550cdac8b50967fce6c0d95897d5a90 100644 (file)
@@ -10,7 +10,9 @@
 **
 *************************************************************************
 **
-** $Id: vdbeblob.c,v 1.8 2007/05/04 18:36:45 danielk1977 Exp $
+** This file contains code used to implement incremental BLOB I/O.
+**
+** $Id: vdbeblob.c,v 1.9 2007/05/05 18:39:25 drh Exp $
 */
 
 #include "sqliteInt.h"
@@ -22,7 +24,6 @@
 ** Valid sqlite3_blob* handles point to Incrblob structures.
 */
 typedef struct Incrblob Incrblob;
-
 struct Incrblob {
   int flags;              /* Copy of "flags" passed to sqlite3_blob_open() */
   int nByte;              /* Size of open blob, in bytes */
@@ -35,13 +36,13 @@ struct Incrblob {
 ** Open a blob handle.
 */
 int sqlite3_blob_open(
-  sqlite3* db,
-  const char *zDb,
-  const char *zTable,
-  const char *zColumn,
-  sqlite_int64 iRow,
+  sqlite3* db,            /* The database connection */
+  const char *zDb,        /* The attached database containing the blob */
+  const char *zTable,     /* The table containing the blob */
+  const char *zColumn,    /* The column containing the blob */
+  sqlite_int64 iRow,      /* The row containing the glob */
   int flags,              /* True -> read/write access, false -> read-only */
-  sqlite3_blob **ppBlob
+  sqlite3_blob **ppBlob   /* Handle for accessing the blob returned here */
 ){
   int nAttempt = 0;
   int iCol;               /* Index of zColumn in row-record */
@@ -235,7 +236,8 @@ blob_open_out:
 }
 
 /*
-** Close a blob handle.
+** Close a blob handle that was previously created using
+** sqlite3_blob_open().
 */
 int sqlite3_blob_close(sqlite3_blob *pBlob){
   Incrblob *p = (Incrblob *)pBlob;
index 8d57a4e5950845224c374220ee1429c2c019ae2a..7e84a899860f1fb32723e8dc0ce04367d218873f 100644 (file)
@@ -9,7 +9,7 @@
 #
 #***********************************************************************
 #
-# $Id: shared.test,v 1.23 2007/04/05 11:25:59 drh Exp $
+# $Id: shared.test,v 1.24 2007/05/05 18:39:25 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -848,9 +848,9 @@ do_test shared-$av.11.8 {
   }
   set res
 } {1 4 {} 7}
-if {[llength [info command sqlite_shared_cache_report]]==1} {
+if {[llength [info command sqlite3_shared_cache_report]]==1} {
   do_test shared-$av.11.9 {
-    sqlite_shared_cache_report 
+    sqlite3_shared_cache_report 
   } [list [file normalize test.db] 2]
 }