diff --git a/manifest b/manifest index c14234b59e..e7c19a1f13 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\sthe\scode\sback\sto\sthe\spoint\swhere\sit\swill\scompile\sthe\sbtree.c\stests.\nMove\sthe\sdefault\skey\scomparison\sroutine\sfrom\sbtree.c\sinto\svdbeaux.c.\nCommented\sout\scode\sin\svdbe.c\sthat\swill\sneed\sto\sbe\sfixed.\s(CVS\s1326) -D 2004-05-08T10:56:11 +C More\sbtree.c\sbug\sfixes.\s(CVS\s1327) +D 2004-05-08T20:07:40 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -23,8 +23,8 @@ F sqlite.def fc4f5734786fe4743cfe2aa98eb2da4b089edb5f F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2 F src/attach.c fa9a58234406d84eeb900517d0c0adc4b2da051a F src/auth.c a2a46e3ed7799134cf3d2dd5ae6650115f26b653 -F src/btree.c 27600f910e247c905389ecf3f246f27e9649cbea -F src/btree.h 07a16dbb8c29291d0768b956649350d8f8c3dac3 +F src/btree.c 26f7caa992e7828db3c045c19a67161150e8ebc4 +F src/btree.h e111dde03373721afbe87e374adf57656c45f0c5 F src/btree_rb.c 47e5b5ec90846af392b5668b34648198ba459561 F src/build.c 21b6645c966970dac51bcccfa8650403a3f56210 F src/copy.c 3c33157f6b4919d6851602b78008c67d466cdadd @@ -40,7 +40,7 @@ F src/main.c b6e249c71c3f815d7551ddf1b914f4bb45a4bd67 F src/md5.c 01d2f55b06316d242749759b6a37186439ef7fe3 F src/os.c 4092dcc87e66f49ed660fae1519569a0cee34da0 F src/os.h fbb2f6595fc34fa351830d88fe1c6b85118f0383 -F src/pager.c 97a675f1653ec2dc2907ebc247b1bae5a4d6ed9a +F src/pager.c 350f5cd153b248c67058cafc75c3f1b7d28c2b0b F src/pager.h 0c95b18f2785b58bfbb2b6f6a221f23caf378687 F src/parse.y d0258aa3cc8b0c5742b07b699d10fa98f3caea7d F src/pragma.c d9f8332a1a87bc4058113ee9686e0c14286d69fd @@ -54,7 +54,7 @@ F src/table.c 882b0ae9524c67758157540dd6467c9a5de52335 F src/tclsqlite.c 21147148e7b57a0bb7409cff5878c60470df9acc F src/test1.c 67a72fa1f5f6d41c838fa97f324f8dbfb4051413 F src/test2.c 8dab493c7eccd2c7bb93a8e31f7db60f14e61b7b -F src/test3.c c5a25235b6b2ada516550eb17b57f8dd002f6b41 +F src/test3.c e9bb798e010ac44221b9d23ed94f9eb76d7a32a8 F src/test4.c 92d2a10380a65d61e5527a556f604bfde16411e8 F src/test5.c eb39aac8fed61bd930b92613cd705c145244074a F src/tokenize.c 256a3cf0ff938cd79774d7f95173d74281912df9 @@ -75,7 +75,7 @@ F test/auth.test 5c4d95cdaf539c0c236e20ce1f71a93e7dde9185 F test/bigfile.test ea904b853ce2d703b16c5ce90e2b54951bc1ae81 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578 F test/bind.test 56a57043b42c4664ca705f6050e56717a8a6699a -F test/btree.test d9d00f8ac8bfa4945861f92c5b14fbe884d874c4 +F test/btree.test c26328987d486893282dd25c0cbbeba2cd9b8f95 F test/btree2.test e3b81ec33dc2f89b3e6087436dfe605b870c9080 F test/btree3.test e597fb59be2ac0ea69c62aaa2064e998e528b665 F test/btree3rb.test 127efcf5cdfcc352054e7db12622b01cdd8b36ac @@ -190,7 +190,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P 1a09a1ada199b76926c64bd79ad39d6d50a75011 -R 020d676c42c3c99a03395fc2bd1d45bd +P 2bca92240b16a51f78661c3ba4d779d231780f8d +R 49eb87c67ff9b6cc18c64077117ae3ba U drh -Z e3b04ec339a83a6885a62a5e117d1378 +Z 62f7ad80381b47a4b8e3828b4a596f0a diff --git a/manifest.uuid b/manifest.uuid index b65f93db38..578bc37138 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2bca92240b16a51f78661c3ba4d779d231780f8d \ No newline at end of file +e9f84ff3fe45a014ab60fabbfd91d19e6d353477 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index fbd1544002..c1b7c0a3ee 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.115 2004/05/08 10:56:11 drh Exp $ +** $Id: btree.c,v 1.116 2004/05/08 20:07:40 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -211,8 +211,6 @@ static const char zMagicHeader[] = "SQLite format 3"; */ struct MemPage { u32 notUsed; - struct Btree *pBt; /* Pointer back to BTree structure */ - unsigned char *aData; /* Pointer back to the start of the page */ u8 isInit; /* True if previously initialized */ u8 idxShift; /* True if Cell indices have changed */ u8 isOverfull; /* Some aCell[] do not fit on page */ @@ -220,13 +218,16 @@ struct MemPage { u8 leaf; /* True if leaf flag is set */ u8 zeroData; /* True if zero data flag is set */ u8 hdrOffset; /* 100 for page 1. 0 otherwise */ - Pgno pgno; /* Page number for this page */ - MemPage *pParent; /* The parent of this page. NULL for root */ int idxParent; /* Index in pParent->aCell[] of this node */ int nFree; /* Number of free bytes on the page */ int nCell; /* Number of entries on this page */ int nCellAlloc; /* Number of slots allocated in aCell[] */ unsigned char **aCell; /* Pointer to start of each cell */ + struct Btree *pBt; /* Pointer back to BTree structure */ + + unsigned char *aData; /* Pointer back to the start of the page */ + Pgno pgno; /* Page number for this page */ + MemPage *pParent; /* The parent of this page. NULL for root */ }; /* @@ -598,13 +599,12 @@ static int initPage( assert( pParent==0 || pParent->pBt==pPage->pBt ); assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) ); assert( pPage->aData == &((unsigned char*)pPage)[-pPage->pBt->pageSize] ); - assert( pPage->isInit==0 || pPage->pParent==pParent ); - if( pPage->isInit ) return SQLITE_OK; - assert( pPage->pParent==0 ); - pPage->pParent = pParent; - if( pParent ){ + assert( pPage->pParent==0 || pPage->pParent==pParent ); + if( pPage->pParent==0 && pParent!=0 ){ + pPage->pParent = pParent; sqlite3pager_ref(pParent->aData); } + if( pPage->isInit ) return SQLITE_OK; pPage->nCell = pPage->nCellAlloc = 0; assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) ); hdr = pPage->hdrOffset; @@ -613,6 +613,8 @@ static int initPage( pPage->intKey = (c & PTF_INTKEY)!=0; pPage->zeroData = (c & PTF_ZERODATA)!=0; pPage->leaf = (c & PTF_LEAF)!=0; + pPage->isOverfull = 0; + pPage->idxShift = 0; pageSize = pPage->pBt->pageSize; /* Initialize the cell count and cell pointers */ @@ -667,6 +669,8 @@ static void zeroPage(MemPage *pPage, int flags){ int hdr = pPage->hdrOffset; int first; + assert( sqlite3pager_pagenumber(data)==pPage->pgno ); + assert( &data[pBt->pageSize] == (unsigned char*)pPage ); assert( sqlite3pager_iswriteable(data) ); memset(&data[hdr], 0, pBt->pageSize - hdr); data[hdr] = flags; @@ -682,6 +686,9 @@ static void zeroPage(MemPage *pPage, int flags){ pPage->leaf = (flags & PTF_LEAF)!=0; pPage->zeroData = (flags & PTF_ZERODATA)!=0; pPage->hdrOffset = hdr; + pPage->isOverfull = 0; + pPage->idxShift = 0; + pPage->isInit = 1; } /* @@ -1002,6 +1009,24 @@ static void invalidateCursors(Btree *pBt){ } } +#ifdef SQLITE_TEST +/* +** Print debugging information about all cursors to standard output. +*/ +void sqlite3BtreeCursorList(Btree *pBt){ + BtCursor *pCur; + for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ + MemPage *pPage = pCur->pPage; + char *zMode = pCur->wrFlag ? "rw" : "ro"; + printf("CURSOR %08x rooted at %4d(%s) currently at %d.%d%s\n", + (int)pCur, pCur->pgnoRoot, zMode, + pPage ? pPage->pgno : 0, pCur->idx, + pCur->isValid ? "" : " eof" + ); + } +} +#endif + /* ** Rollback the transaction in progress. All cursors will be ** invalided by this operation. Any attempt to use a cursor @@ -1536,8 +1561,9 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){ */ static int isRootPage(MemPage *pPage){ MemPage *pParent = pPage->pParent; - assert( pParent==0 || pParent->isInit ); - if( pParent==0 || (pParent->pgno==1 && pParent->nCell==0) ) return 1; + if( pParent==0 ) return 1; + if( pParent->pgno>1 ) return 0; + if( get2byte(&pParent->aData[pParent->hdrOffset+3])==0 ) return 1; return 0; } @@ -2310,6 +2336,14 @@ static void relinkCellList(MemPage *pPage){ put2byte(&pPage->aData[idxFrom], 0); } +/* +** GCC does not define the offsetof() macro so we'll have to do it +** ourselves. +*/ +#ifndef offsetof +#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) +#endif + /* ** Move the content of the page at pFrom over to pTo. The pFrom->aCell[] ** pointers that point into pFrom->aData[] must be adjusted to point @@ -2318,7 +2352,7 @@ static void relinkCellList(MemPage *pPage){ ** ** Over this operation completes, the meta data for pFrom is zeroed. */ -static void copyPage(MemPage *pTo, MemPage *pFrom){ +static void movePage(MemPage *pTo, MemPage *pFrom){ uptr from, to; int i; int pageSize; @@ -2326,10 +2360,12 @@ static void copyPage(MemPage *pTo, MemPage *pFrom){ assert( pTo->hdrOffset==0 ); ofst = pFrom->hdrOffset; - pageSize = pTo->pBt->pageSize; + pageSize = pFrom->pBt->pageSize; sqliteFree(pTo->aCell); - memcpy(pTo->aData, &pFrom->aData[ofst], pageSize - ofst + sizeof(MemPage)); - memset(pFrom, 0, sizeof(MemPage)); + memcpy(pTo->aData, &pFrom->aData[ofst], pageSize - ofst); + memcpy(pTo, pFrom, offsetof(MemPage, aData)); + pFrom->isInit = 0; + pFrom->aCell = 0; assert( pTo->aData[5]<155 ); pTo->aData[5] += ofst; pTo->isOverfull = pFrom->isOverfull; @@ -2408,6 +2444,7 @@ static int balance(MemPage *pPage){ int usableSpace; /* Bytes in pPage beyond the header */ int pageFlags; /* Value of pPage->aData[0] */ int subtotal; /* Subtotal of bytes in cells on one page */ + MemPage *extraUnref = 0; /* Unref this page if not zero */ MemPage *apOld[NB]; /* pPage and up to two siblings */ Pgno pgnoOld[NB]; /* Page numbers for each page in apOld[] */ MemPage *apCopy[NB]; /* Private copies of apOld[] pages */ @@ -2510,15 +2547,17 @@ static int balance(MemPage *pPage){ rc = allocatePage(pBt, &pChild, &pgnoChild, pPage->pgno); if( rc ) return rc; assert( sqlite3pager_iswriteable(pChild->aData) ); - copyPage(pChild, pPage); + movePage(pChild, pPage); + assert( pChild->aData[0]==pPage->aData[pPage->hdrOffset] ); pChild->pParent = pPage; - pChild->idxParent = 0; sqlite3pager_ref(pPage->aData); + pChild->idxParent = 0; pChild->isOverfull = 1; - zeroPage(pPage, pPage->aData[pPage->hdrOffset] & ~PTF_LEAF); + zeroPage(pPage, pChild->aData[0] & ~PTF_LEAF); put4byte(&pPage->aData[pPage->hdrOffset+6], pChild->pgno); pParent = pPage; pPage = pChild; + extraUnref = pChild; } rc = sqlite3pager_write(pParent->aData); if( rc ) return rc; @@ -2593,10 +2632,11 @@ static int balance(MemPage *pPage){ ** process of being overwritten. */ for(i=0; iaData = &((u8*)apCopy)[-pBt->pageSize]; - copyPage(apCopy[i], apOld[i]); + MemPage *p = apCopy[i] = (MemPage*)&aCopy[i+1][-sizeof(MemPage)]; + p->aData = &((u8*)p)[-pBt->pageSize]; + p->aCell = 0; + p->hdrOffset = 0; + movePage(p, apOld[i]); } /* @@ -2621,11 +2661,12 @@ static int balance(MemPage *pPage){ nCell++; } if( ileaf ){ assert( leafCorrection==0 ); /* The right pointer of the child page pOld becomes the left @@ -2677,18 +2718,19 @@ static int balance(MemPage *pPage){ assert( pPage->pgno>1 ); pageFlags = pPage->aData[0]; for(i=0; iaData); }else{ - rc = allocatePage(pBt, &apNew[i], &pgnoNew[i], pgnoNew[i-1]); + rc = allocatePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1]); if( rc ) goto balance_cleanup; + apNew[i] = pNew; } nNew++; - zeroPage(apNew[i], pageFlags); - apNew[i]->isInit = 1; + zeroPage(pNew, pageFlags); } /* Free any old pages that were not reused as new pages. @@ -2696,7 +2738,7 @@ static int balance(MemPage *pPage){ while( iaData); + releasePage(apOld[i]); apOld[i] = 0; i++; } @@ -2790,7 +2832,10 @@ static int balance(MemPage *pPage){ /* ** balance the parent page. */ + assert( pPage->isInit ); + assert( pParent->isInit ); rc = balance(pParent); + /* ** Cleanup before returning. @@ -2799,7 +2844,6 @@ balance_cleanup: for(i=0; ipParent); sqliteFree(apCopy[i]->aCell); } } @@ -2807,6 +2851,7 @@ balance_cleanup: releasePage(apNew[i]); } releasePage(pParent); + releasePage(extraUnref); return rc; } @@ -2958,6 +3003,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){ unsigned char *pNext; int szNext; int notUsed; + unsigned char tempbuf[4]; getTempCursor(pCur, &leafCur); rc = sqlite3BtreeNext(&leafCur, ¬Used); if( rc!=SQLITE_OK ){ @@ -2969,10 +3015,12 @@ int sqlite3BtreeDelete(BtCursor *pCur){ dropCell(pPage, pCur->idx, cellSize(pPage, pCell)); pNext = leafCur.pPage->aCell[leafCur.idx]; szNext = cellSize(leafCur.pPage, pNext); - insertCell(pPage, pCur->idx, &pNext[-4], szNext+4); + memcpy(tempbuf, &pNext[-2], 4); put4byte(&pNext[-2], pgnoChild); + insertCell(pPage, pCur->idx, &pNext[-4], szNext+4); rc = balance(pPage); if( rc ) return rc; + memcpy(&pNext[-2], tempbuf, 4); dropCell(leafCur.pPage, leafCur.idx, szNext); rc = balance(leafCur.pPage); releaseTempCursor(&leafCur); @@ -3158,7 +3206,7 @@ int sqlite3BtreeUpdateMeta(Btree *pBt, int idx, u32 iMeta){ int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){ int rc; MemPage *pPage; - int i, j; + int i, j, c; int nFree; u16 idx; int hdr; @@ -3172,6 +3220,10 @@ int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){ } hdr = pPage->hdrOffset; data = pPage->aData; + c = data[hdr]; + pPage->intKey = (c & PTF_INTKEY)!=0; + pPage->zeroData = (c & PTF_ZERODATA)!=0; + pPage->leaf = (c & PTF_LEAF)!=0; printf("PAGE %d: flags=0x%02x frag=%d\n", pgno, data[hdr], data[hdr+5]); i = 0; diff --git a/src/btree.h b/src/btree.h index 77e3cd85c0..38bb976025 100644 --- a/src/btree.h +++ b/src/btree.h @@ -13,7 +13,7 @@ ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** -** @(#) $Id: btree.h,v 1.40 2004/05/08 08:23:23 danielk1977 Exp $ +** @(#) $Id: btree.h,v 1.41 2004/05/08 20:07:40 drh Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ @@ -94,12 +94,10 @@ struct Pager *sqlite3BtreePager(Btree*); #ifdef SQLITE_TEST int sqlite3BtreeCursorDump(BtCursor*, int*); +void sqlite3BtreeCursorList(Btree*); int sqlite3BtreeFlags(BtCursor*); int sqlite3BtreePageDump(Btree*, int, int recursive); #endif #endif /* _BTREE_H_ */ - - - diff --git a/src/pager.c b/src/pager.c index 5122f52a8b..f8c7ba06f8 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.104 2004/05/08 08:23:28 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.105 2004/05/08 20:07:40 drh Exp $ */ #include "os.h" /* Must be first to enable large file support */ #include "sqliteInt.h" @@ -1115,11 +1115,14 @@ Pgno sqlite3pager_pagenumber(void *pData){ } /* -** Increment the reference count for a page. If the page is -** currently on the freelist (the reference count is zero) then +** The page_ref() function increments the reference count for a page. +** If the page is currently on the freelist (the reference count is zero) then ** remove it from the freelist. +** +** For non-test systems, page_ref() is a macro that calls _page_ref() +** online of the reference count is zero. For test systems, page_ref() +** is a real function so that we can set breakpoints and trace it. */ -#define page_ref(P) ((P)->nRef==0?_page_ref(P):(void)(P)->nRef++) static void _page_ref(PgHdr *pPg){ if( pPg->nRef==0 ){ /* The page is currently on the freelist. Remove it. */ @@ -1143,6 +1146,18 @@ static void _page_ref(PgHdr *pPg){ pPg->nRef++; REFINFO(pPg); } +#ifdef SQLITE_TEST + static void page_ref(PgHdr *pPg){ + if( pPg->nRef==0 ){ + _page_ref(pPg); + }else{ + pPg->nRef++; + REFINFO(pPg); + } + } +#else +# define page_ref(P) ((P)->nRef==0?_page_ref(P):(void)(P)->nRef++) +#endif /* ** Increment the reference count for a page. The input pointer is @@ -2220,6 +2235,3 @@ void sqlite3pager_refdump(Pager *pPager){ } } #endif - - - diff --git a/src/test3.c b/src/test3.c index d79dc58496..1870202a08 100644 --- a/src/test3.c +++ b/src/test3.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test3.c,v 1.30 2004/05/08 08:23:39 danielk1977 Exp $ +** $Id: test3.c,v 1.31 2004/05/08 20:07:40 drh Exp $ */ #include "sqliteInt.h" #include "pager.h" @@ -508,6 +508,29 @@ static int btree_integrity_check( return TCL_OK; } +/* +** Usage: btree_cursor_list ID +** +** Print information about all cursors to standard output for debugging. +*/ +static int btree_cursor_list( + void *NotUsed, + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int argc, /* Number of arguments */ + const char **argv /* Text of each argument */ +){ + Btree *pBt; + + if( argc!=2 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " ID\"", 0); + return TCL_ERROR; + } + if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; + sqlite3BtreeCursorList(pBt); + return SQLITE_OK; +} + /* ** Usage: btree_cursor ID TABLENUM WRITEABLE ** @@ -1075,6 +1098,7 @@ int Sqlitetest3_Init(Tcl_Interp *interp){ { "btree_first", (Tcl_CmdProc*)btree_first }, { "btree_last", (Tcl_CmdProc*)btree_last }, { "btree_cursor_dump", (Tcl_CmdProc*)btree_cursor_dump }, + { "btree_cursor_list", (Tcl_CmdProc*)btree_cursor_list }, { "btree_integrity_check", (Tcl_CmdProc*)btree_integrity_check }, { "btree_breakpoint", (Tcl_CmdProc*)btree_breakpoint }, }; @@ -1087,6 +1111,3 @@ int Sqlitetest3_Init(Tcl_Interp *interp){ TCL_LINK_INT); return TCL_OK; } - - - diff --git a/test/btree.test b/test/btree.test index 49f0dda4bf..fd70683d37 100644 --- a/test/btree.test +++ b/test/btree.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this script is btree database backend # -# $Id: btree.test,v 1.19 2004/05/08 10:56:20 drh Exp $ +# $Id: btree.test,v 1.20 2004/05/08 20:07:40 drh Exp $ set testdir [file dirname $argv0] @@ -827,28 +827,31 @@ do_test btree-10.2 { lindex [btree_pager_stats $::b1] 1 } {2} do_test btree-10.3 { - for {set i 1} {$i<=20} {incr i} { + for {set i 1} {$i<=30} {incr i} { set key [format %03d $i] set data "*** $key *** $key *** $key *** $key ***" btree_insert $::c1 $key $data } select_keys $::c1 -} {001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020} -#btree_page_dump $::b1 7 -btree_page_dump $::b1 1 -#btree_page_dump $::b1 6 +} {001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030} +#btree_tree_dump $::b1 2 do_test btree-10.4 { - btree_move_to $::c1 011 + # The divider entry is 012. This is found by uncommenting the + # btree_tree_dump call above and looking at the tree. If the page size + # changes, this test will no longer work. + btree_move_to $::c1 012 btree_delete $::c1 select_keys $::c1 -} {001 002 003 004 005 006 007 008 009 010 012 013 014 015 016 017 018 019 020} -#btree_tree_dump $::b1 2 +} {001 002 003 004 005 006 007 008 009 010 011 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030} #btree_pager_ref_dump $::b1 -for {set i 1} {$i<=20} {incr i} { +#btree_tree_dump $::b1 2 +for {set i 1} {$i<=30} {incr i} { + # Check the number of unreference pages. This should be 3 in most cases, + # but 2 when the cursor is pointing to the divider entry which is now 013. do_test btree-10.5.$i { btree_move_to $::c1 [format %03d $i] lindex [btree_pager_stats $::b1] 1 - } {2} + } [expr {$i==13?2:3}] #btree_pager_ref_dump $::b1 #btree_tree_dump $::b1 2 } @@ -857,18 +860,31 @@ for {set i 1} {$i<=20} {incr i} { # catch {unset ::data} catch {unset ::key} -for {set i 21} {$i<=1000} {incr i} { +for {set i 31} {$i<=1000} {incr i} { +if {$i==88} { +set pager_refinfo_enable 1 +btree_tree_dump $b1 2 +btree_pager_ref_dump $b1 +btree_cursor_list $b1 +} do_test btree-11.1.$i.1 { set key [format %03d $i] set ::data "*** $key *** $key *** $key *** $key ***" btree_insert $::c1 $key $data + btree_move_to $::c1 $key btree_key $::c1 } [format %03d $i] +if {$i==88} { +btree_pager_ref_dump $b1 +btree_cursor_list $b1 +btree_tree_dump $b1 2 +exit +} do_test btree-11.1.$i.2 { btree_data $::c1 } $::data set ::key [format %03d [expr {$i/2}]] - if {$::key=="011"} {set ::key 010} + if {$::key=="012"} {set ::key 013} do_test btree-11.1.$i.3 { btree_move_to $::c1 $::key btree_key $::c1