diff --git a/manifest b/manifest index 56938aa9e9..9c8246f93c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Pager\stests\sworking.\s(CVS\s1308) -D 2004-04-26T14:10:21 +C Sync\sall\sversion\s3\schanges.\s(CVS\s1309) +D 2004-04-29T14:42:46 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -23,7 +23,7 @@ F sqlite.def fc4f5734786fe4743cfe2aa98eb2da4b089edb5f F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2 F src/attach.c b01db0d3211f673d8e670abf7eaad04591d40d14 F src/auth.c 4fa3b05bd19445d1c474d6751c4a508d6ea0abe1 -F src/btree.c 4e2b50ae03bd4d9e678bda14b08307d80dd4471c +F src/btree.c 09272a46501fb5e60474c0b5c1e32c825086067f F src/btree.h 858659c6605ae07a2a0fb3d176b25573d30f27c5 F src/btree_rb.c 99feb3ff835106d018a483a1ce403e5cf9c718bc F src/build.c 76fbca30081decd6615dee34b48c927ed5063752 @@ -188,7 +188,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P ce0bbd3a7159e12c86c5cde6571d6668b234827b -R e6250126bdd2ced9348d9f2d5069495a +P 910067a200c4b25b5d813a84146673d3d1c80952 +R 9774fd5f44f9196be5f8b828df0f1a01 U drh -Z 07ad078caa4fedefbf47bb778c51fa1e +Z 1f01b8b1967a026f92cc6d5ed5f03774 diff --git a/manifest.uuid b/manifest.uuid index 067e908d38..27ead59fc4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -910067a200c4b25b5d813a84146673d3d1c80952 \ No newline at end of file +51892d6cdc739bb049fdfce8301354312167c181 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index abccfb851b..bd846f95e6 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.105 2004/04/26 14:10:21 drh Exp $ +** $Id: btree.c,v 1.106 2004/04/29 14:42:46 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -1519,6 +1519,22 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){ return SQLITE_OK; } +/* +** Return true if the page is the virtual root of its table. +** +** The virtual root page is the root page for most tables. But +** for the table rooted on page 1, sometime the real root page +** is empty except for the right-pointer. In such cases the +** virtual root page is the page that the right-pointer of page +** 1 is pointing to. +*/ +static int isRootPage(MemPage *pPage){ + MemPage *pParent = pPage->pParent; + assert( pParent==0 || pParent->isInit ); + if( pParent || (pParent->pgno==1 && pParent->nCell==0) ) return 1; + return 0; +} + /* ** Move the cursor up to the parent page. ** @@ -1535,6 +1551,7 @@ static void moveToParent(BtCursor *pCur){ pPage = pCur->pPage; assert( pPage!=0 ); + assert( !isRootPage(pPage) ); pParent = pPage->pParent; assert( pParent!=0 ); idxParent = pPage->idxParent; @@ -1580,14 +1597,21 @@ static int moveToRoot(BtCursor *pCur){ int rc; Btree *pBt = pCur->pBt; - rc = sqlitepager_get(pBt->pPager, pCur->pgnoRoot, &pRoot); + rc = getPage(pBt, pCur->pgnoRoot, &pRoot); if( rc ) return rc; rc = initPage(pRoot, 0); if( rc ) return rc; releasePage(pCur->pPage); pCur->pPage = pRoot; pCur->idx = 0; - return SQLITE_OK; + if( pRoot->nCell==0 && !pRoot->leaf ){ + Pgno subpage; + assert( pRoot->pgno==1 ); + subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+6]); + assert( subpage>0 ); + rc = movetoChild(pCur, subpage); + } + return rc; } /* @@ -1802,7 +1826,7 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ return rc; } do{ - if( pPage->pParent==0 ){ + if( isRootPage(pPage) ){ *pRes = 1; return SQLITE_OK; } @@ -1855,7 +1879,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ rc = moveToRightmost(pCur); }else{ while( pCur->idx==0 ){ - if( pPage->pParent==0 ){ + if( isRootPage(pPage) ){ if( pRes ) *pRes = 1; return SQLITE_OK; } @@ -2374,20 +2398,35 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){ MemPage *pChild; assert( pPage->isInit ); if( pPage->nCell==0 ){ - if( pPage->u.hdr.rightChild ){ - /* - ** The root page is empty. Copy the one child page - ** into the root page and return. This reduces the depth - ** of the BTree by one. + if( pPage->leaf ){ + /* The table is completely empty */ + relinkCellList(pPage); + }else{ + /* The root page is empty but has one child. Transfer the + ** information from that one child into the root page if it + ** will fit. This reduces the depth of the BTree by one. + ** + ** If the root page is page 1, it has less space available than + ** the child, so it might not be able to hold all of the information + ** in the child. If this is the case, then do not do the transfer. + ** Leave page 1 empty except for the right-pointer to the child page. + ** The child page becomes the virtual root of the tree. */ - pgnoChild = SWAB32(pBt, pPage->u.hdr.rightChild); - rc = sqlitepager_get(pBt->pPager, pgnoChild, (void**)&pChild); + pgnoChild = get4byte(pPage->aData[pPage->hdrOffset+6]); + assert( pgnoChild>0 && pgnoChild<=sqlit3pager_pagecount(pBt->pPager) ); + rc = getPage(pBt, pgnoChild, &pChild); if( rc ) return rc; - memcpy(pPage, pChild, SQLITE_USABLE_SIZE); - pPage->isInit = 0; - rc = initPage(pBt, pPage, sqlitepager_pagenumber(pPage), 0); - assert( rc==SQLITE_OK ); - reparentChildPages(pBt, pPage); + if( pPage->pgno==1 ){ + rc = initPage(pChild); + if( rc ) return rc; + if( pChild->nFree>=100 ){ + } + }else{ + memcpy(pPage, pChild, SQLITE_USABLE_SIZE); + pPage->isInit = 0; + rc = initPage(pBt, pPage, sqlitepager_pagenumber(pPage), 0); + assert( rc==SQLITE_OK ); + reparentChildPages(pBt, pPage); if( pCur && pCur->pPage==pChild ){ sqlitepager_unref(pChild); pCur->pPage = pPage;