diff --git a/manifest b/manifest index fe94c740c9..c917ea865d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sautoincrement\sso\sthat\sit\sworks\swith\striggers\sthat\salso\sdo\r\nautoincrement\sinserts,\seven\smultiple\sinserts\sinto\sthe\ssame\stable.\r\nTicket\s#3928\s(CVS\s6807) -D 2009-06-23T20:28:54 +C Simplify\sthings\sby\srolling\sthe\sfunctionality\sof\sbalance_shallower()\sinto\sbalance_nonroot().\s(CVS\s6808) +D 2009-06-24T05:40:34 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 8b8fb7823264331210cddf103831816c286ba446 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -106,9 +106,9 @@ F src/auth.c 98db07c2088455797678eb1031f42d4d94d18a71 F src/backup.c ff50af53184a5fd7bdee4d620b5dabef74717c79 F src/bitvec.c 0ef0651714728055d43de7a4cdd95e703fac0119 F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c -F src/btree.c 807e32c181e681ffd3468d114b5cb11c63984842 +F src/btree.c 699c333dd98db2498eb17ca43b2a5482c9dd098f F src/btree.h f70b694e8c163227369a66863b01fbff9009f323 -F src/btreeInt.h 7267e965e34314aa2bddbdde268b31e1034eda9c +F src/btreeInt.h 55346bc14b939ad41b297942e8b1b581e960fb99 F src/build.c d930b3899aea564f01a581e0e9429d92fb5f98f0 F src/callback.c cb68b21b0d4ae7d11ae0e487933bce3323784dcf F src/complete.c 5ad5c6cd4548211867c204c41a126d73a9fbcea0 @@ -737,7 +737,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746 -P c5dc80e6bdd18a5ada728c8d5c9403ac233f1c9a -R 8916621e1801546a3d0feafac918adbe -U drh -Z cb8dc29a045e11a78c5fa19e64b5f95b +P 1330993de8eae7baeec24100216158063c9bdc19 +R a93d21d5217aa847ca2406219efba4db +U danielk1977 +Z ce9bb99781cb9e1be1b1a4518af4f1e5 diff --git a/manifest.uuid b/manifest.uuid index 09a7f53599..02426e0d74 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1330993de8eae7baeec24100216158063c9bdc19 \ No newline at end of file +11750c6aee6aa05b2627ad9dfb2fbcdfe8944168 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index c874018161..3f833d9532 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.641 2009/06/23 16:40:18 danielk1977 Exp $ +** $Id: btree.c,v 1.642 2009/06/24 05:40:34 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -5388,47 +5388,6 @@ static int copyNodeContent(MemPage *pFrom, MemPage *pTo){ return rc; } -/* -** This routine is called on the root page of a btree when the root -** page contains no cells. This is an opportunity to make the tree -** shallower by one level. -*/ -static int balance_shallower(MemPage *pRoot, MemPage *pChild){ - /* 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 tree by one. - ** - ** If the root page is page 1, it has less space available than - ** its child (due to the 100 byte header that occurs at the beginning - ** of the database fle), so it might not be able to hold all of the - ** information currently contained 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. - */ - int rc = SQLITE_OK; /* Return code */ - int const hdr = pRoot->hdrOffset; /* Offset of root page header */ - - assert( sqlite3_mutex_held(pRoot->pBt->mutex) ); - assert( pRoot->nCell==0 ); - assert( pChild->pgno==get4byte(&pRoot->aData[pRoot->hdrOffset+8]) ); - assert( hdr==0 || pRoot->pgno==1 ); - - if( pChild->nFree>=hdr ){ - if( hdr ){ - rc = defragmentPage(pChild); - } - if( rc==SQLITE_OK ){ - rc = copyNodeContent(pChild, pRoot); - } - if( rc==SQLITE_OK ){ - rc = freePage(pChild); - } - } - - return rc; -} - /* ** This routine redistributes cells on the iParentIdx'th child of pParent ** (hereafter "the page") and up to 2 siblings so that all pages have about the @@ -5922,38 +5881,60 @@ static int balance_nonroot( memcpy(&apNew[nNew-1]->aData[8], zChild, 4); } - /* Fix the pointer-map entries for all the cells that were shifted around. - ** There are several different types of pointer-map entries that need to - ** be dealt with by this routine. Some of these have been set already, but - ** many have not. The following is a summary: - ** - ** 1) The entries associated with new sibling pages that were not - ** siblings when this function was called. These have already - ** been set. We don't need to worry about old siblings that were - ** moved to the free-list - the freePage() code has taken care - ** of those. - ** - ** 2) The pointer-map entries associated with the first overflow - ** page in any overflow chains used by new divider cells. These - ** have also already been taken care of by the insertCell() code. - ** - ** 3) If the sibling pages are not leaves, then the child pages of - ** cells stored on the sibling pages may need to be updated. - ** - ** 4) If the sibling pages are not internal intkey nodes, then any - ** overflow pages used by these cells may need to be updated - ** (internal intkey nodes never contain pointers to overflow pages). - ** - ** 5) If the sibling pages are not leaves, then the pointer-map - ** entries for the right-child pages of each sibling may need - ** to be updated. - ** - ** Cases 1 and 2 are dealt with above by other code. The following - ** block deals with cases 3 and 4. Since setting a pointer map entry - ** is a relatively expensive operation, this code only sets pointer - ** map entries for child or overflow pages that have actually moved - ** between pages. */ - if( ISAUTOVACUUM ){ + if( isRoot && pParent->nCell==0 && pParent->hdrOffset<=apNew[0]->nFree ){ + /* The root page of the b-tree now contains no cells. The only sibling + ** page is the right-child of the parent. Copy the contents of the + ** child page into the parent, decreasing the overall height of the + ** b-tree structure by one. This is described as the "balance-shallower" + ** sub-algorithm in some documentation. + ** + ** If this is an auto-vacuum database, the call to copyNodeContent() + ** sets all pointer-map entries corresponding to database image pages + ** for which the pointer is stored within the content being copied. + ** + ** The second assert below verifies that the child page is defragmented + ** (it must be, as it was just reconstructed using assemblePage()). This + ** is important if the parent page happens to be page 1 of the database + ** image. */ + assert( nNew==1 ); + assert( apNew[0]->nFree == + (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2) + ); + if( SQLITE_OK==(rc = copyNodeContent(apNew[0], pParent)) ){ + rc = freePage(apNew[0]); + } + }else if( ISAUTOVACUUM ){ + /* Fix the pointer-map entries for all the cells that were shifted around. + ** There are several different types of pointer-map entries that need to + ** be dealt with by this routine. Some of these have been set already, but + ** many have not. The following is a summary: + ** + ** 1) The entries associated with new sibling pages that were not + ** siblings when this function was called. These have already + ** been set. We don't need to worry about old siblings that were + ** moved to the free-list - the freePage() code has taken care + ** of those. + ** + ** 2) The pointer-map entries associated with the first overflow + ** page in any overflow chains used by new divider cells. These + ** have also already been taken care of by the insertCell() code. + ** + ** 3) If the sibling pages are not leaves, then the child pages of + ** cells stored on the sibling pages may need to be updated. + ** + ** 4) If the sibling pages are not internal intkey nodes, then any + ** overflow pages used by these cells may need to be updated + ** (internal intkey nodes never contain pointers to overflow pages). + ** + ** 5) If the sibling pages are not leaves, then the pointer-map + ** entries for the right-child pages of each sibling may need + ** to be updated. + ** + ** Cases 1 and 2 are dealt with above by other code. The next + ** block deals with cases 3 and 4 and the one after that, case 5. Since + ** setting a pointer map entry is a relatively expensive operation, this + ** code only sets pointer map entries for child or overflow pages that have + ** actually moved between pages. */ MemPage *pNew = apNew[0]; MemPage *pOld = apCopy[0]; int nOverflow = pOld->nOverflow; @@ -6032,16 +6013,6 @@ static int balance_nonroot( TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n", nOld, nNew, nCell)); - if( rc==SQLITE_OK && pParent->nCell==0 && isRoot ){ - /* The root page of the b-tree now contains no cells. If the root-page - ** is not also a leaf page, it will have a single child page. Call - ** balance_shallower to attempt to copy the contents of the single - ** child-page into the root page (this may not be possible if the - ** root page is page 1). */ - assert( nNew==1 ); - rc = balance_shallower(pParent, apNew[0]); - } - /* ** Cleanup before returning. */ @@ -6127,11 +6098,6 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){ ** balance_quick() ** balance_deeper() ** balance_nonroot() -** -** If built with SQLITE_DEBUG, pCur->pagesShuffled is set to true if -** balance_shallower(), balance_deeper() or balance_nonroot() is called. -** If none of these functions are invoked, pCur->pagesShuffled is left -** unmodified. */ static int balance(BtCursor *pCur){ int rc = SQLITE_OK; @@ -6161,7 +6127,6 @@ static int balance(BtCursor *pCur){ pCur->aiIdx[1] = 0; assert( pCur->apPage[1]->nOverflow ); } - VVA_ONLY( pCur->pagesShuffled = 1 ); }else{ break; } @@ -6229,7 +6194,6 @@ static int balance(BtCursor *pCur){ ** balance_nonroot(), or just before this function returns, whichever ** comes first. */ pFree = pSpace; - VVA_ONLY( pCur->pagesShuffled = 1 ); } } diff --git a/src/btreeInt.h b/src/btreeInt.h index 7e6ce02774..5401ca6dc8 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btreeInt.h,v 1.48 2009/06/22 12:05:10 drh Exp $ +** $Id: btreeInt.h,v 1.49 2009/06/24 05:40:34 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -475,9 +475,6 @@ struct BtCursor { #ifndef SQLITE_OMIT_INCRBLOB u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */ Pgno *aOverflow; /* Cache of overflow page locations */ -#endif -#ifndef NDEBUG - u8 pagesShuffled; /* True if Btree pages are rearranged by balance()*/ #endif i16 iPage; /* Index of current page in apPage */ MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */