-C Enhance\sthe\sperformance\sof\sauto-vacuum\sdatabases\sby\sreducing\sthe\snumber\sof\spointer-map\sentries\swritten\sduring\stree\sbalancing.\sAlso\sfix\sbugs\sin\sbalance_quick().\s(CVS\s2216)
-D 2005-01-15T12:45:51
+C Move\sduplicate\scode\sto\supdate\spointer-map\swrt\soverflow\spages\sinto\sa\sfunction.\s(CVS\s2217)
+D 2005-01-16T08:00:01
F Makefile.in 6ce51dde6a8fe82fc12f20dec750572f6a19f56a
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689
F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea
-F src/btree.c 426032061fb39b1bfcbf1d58915d5a6346bb4e22
+F src/btree.c a007420eaced555faf95bba82260a6581a53ce24
F src/btree.h 74d19cf40ab49fd69abe9e4e12a6c321ad86c497
F src/build.c af1296e8a21a406b4f4c4f1e1365e075071219f3
F src/cursor.c f883813759742068890b1f699335872bfa8fdf41
F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
F www/whentouse.tcl c3b50d3ac31c54be2a1af9b488a89d22f1e6e746
-P 92f9d2b2f480fccfa6e8b70a1d19058b92a4ea8f
-R 0a0af1f143c2a17b3aa82ad2aba89b86
+P 0ae29538ccccfc237904cbcfb4507074db0f5905
+R 983f36f11ba46bcdb0dbd6d8fd3e81a2
U danielk1977
-Z 0cdc37c80cb8604b1387cf29891ba583
+Z ca69fe793079786f4174a1ca82437b0c
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.234 2005/01/15 12:45:51 danielk1977 Exp $
+** $Id: btree.c,v 1.235 2005/01/16 08:00:01 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
return info.nSize;
}
+#ifndef SQLITE_OMIT_AUTOVACUUM
/*
-** If pCell, part of pPage, contains a pointer to an overflow page,
-** return the overflow page number. Otherwise return 0.
+** If the cell with index iCell on page pPage contains a pointer
+** to an overflow page, insert an entry into the pointer-map
+** for the overflow page.
*/
-static Pgno ovflPagePtr(MemPage *pPage, u8 *pCell){
- CellInfo info;
- parseCellPtr(pPage, pCell, &info);
- if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){
- return get4byte(&pCell[info.iOverflow]);
+static int ptrmapPutOvfl(MemPage *pPage, int iCell){
+ u8 *pCell;
+ pCell = findOverflowCell(pPage, iCell);
+ if( pCell ){
+ CellInfo info;
+ parseCellPtr(pPage, pCell, &info);
+ if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){
+ Pgno ovfl = get4byte(&pCell[info.iOverflow]);
+ return ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno);
+ }
}
- return 0;
+ return SQLITE_OK;
}
+#endif
+
/*
** Do sanity checking on a page. Throw an exception if anything is
int szCell;
CellInfo info;
Btree *pBt = pPage->pBt;
-
- u8 parentCell[64]; /* How big should this be? */
- int parentIdx = pParent->nCell;
- int parentSize;
+ int parentIdx = pParent->nCell; /* pParent new divider cell index */
+ int parentSize; /* Size of new divider cell */
+ u8 parentCell[64]; /* Space for the new divider cell */
/* Allocate a new page. Insert the overflow cell from pPage
** into it. Then remove the overflow cell from pPage.
assemblePage(pNew, 1, &pCell, &szCell);
pPage->nOverflow = 0;
+ /* Set the parent of the newly allocated page to pParent. */
+ pNew->pParent = pParent;
+ sqlite3pager_ref(pParent->aData);
+
/* pPage is currently the right-child of pParent. Change this
** so that the right-child is the new page allocated above and
- ** pPage is the next-to-right child. Then balance() the parent
- ** page, in case it is now overfull.
+ ** pPage is the next-to-right child.
*/
assert( pPage->nCell>0 );
parseCellPtr(pPage, findCell(pPage, pPage->nCell-1), &info);
rc = fillInCell(pParent, parentCell, 0, info.nKey, 0, 0, &parentSize);
if( rc!=SQLITE_OK ){
- return SQLITE_OK;
+ return rc;
}
assert( parentSize<64 );
rc = insertCell(pParent, parentIdx, parentCell, parentSize, 0, 4);
if( rc!=SQLITE_OK ){
- return SQLITE_OK;
+ return rc;
}
put4byte(findOverflowCell(pParent,parentIdx), pPage->pgno);
put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew);
- pNew->pParent = pParent;
- sqlite3pager_ref(pParent->aData);
-
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ /* If this is an auto-vacuum database, update the pointer map
+ ** with entries for the new page, and any pointer from the
+ ** cell on the page to an overflow page.
+ */
if( pBt->autoVacuum ){
rc = ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno);
if( rc!=SQLITE_OK ){
return rc;
}
- pCell = findCell(pNew, 0);
- parseCellPtr(pNew, pCell, &info);
- if( info.nData>info.nLocal ){
- Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
- rc = ptrmapPut(pBt, pgnoOvfl, PTRMAP_OVERFLOW1, pgnoNew);
- if( rc!=SQLITE_OK ){
- return rc;
- }
+ rc = ptrmapPutOvfl(pNew, 0);
+ if( rc!=SQLITE_OK ){
+ return rc;
}
}
+#endif
+ /* Release the reference to the new page and balance the parent page,
+ ** in case the divider cell inserted caused it to become overfull.
+ */
releasePage(pNew);
return balance(pParent, 0);
}
if( pBt->autoVacuum ){
for(k=j; k<cntNew[i]; k++){
if( aFrom[k]==0xFF || apCopy[aFrom[k]]->pgno!=pNew->pgno ){
- Pgno ovfl = ovflPagePtr(pNew, findCell(pNew, k-j));
- if( ovfl ){
- rc = ptrmapPut(pBt, ovfl, PTRMAP_OVERFLOW1, pNew->pgno);
- if( rc!=SQLITE_OK ){
- goto balance_cleanup;
- }
+ rc = ptrmapPutOvfl(pNew, k-j);
+ if( rc!=SQLITE_OK ){
+ goto balance_cleanup;
}
}
}
** that the cell just inserted points to (if any).
*/
if( pBt->autoVacuum && !leafData ){
- Pgno ovfl = ovflPagePtr(pParent, findOverflowCell(pParent, nxDiv));
- if( ovfl ){
- rc = ptrmapPut(pBt, ovfl, PTRMAP_OVERFLOW1, pParent->pgno);
- if( rc!=SQLITE_OK ){
- goto balance_cleanup;
- }
+ rc = ptrmapPutOvfl(pParent, nxDiv);
+ if( rc!=SQLITE_OK ){
+ goto balance_cleanup;
}
}
#endif
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pBt->autoVacuum ){
for(i=0; i<pPage->nCell; i++){
- Pgno ovfl = ovflPagePtr(pPage, findCell(pPage, i));
- if( ovfl ){
- rc = ptrmapPut(pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno);
- if( rc!=SQLITE_OK ){
- goto end_shallow_balance;
- }
+ rc = ptrmapPutOvfl(pPage, i);
+ if( rc!=SQLITE_OK ){
+ goto end_shallow_balance;
}
}
}
rc = ptrmapPut(pBt, pChild->pgno, PTRMAP_BTREE, pPage->pgno);
if( rc ) return rc;
for(i=0; i<pChild->nCell; i++){
- Pgno pgno = ovflPagePtr(pChild, findOverflowCell(pChild, i));
- if( pgno ){
- rc = ptrmapPut(pBt, pgno, PTRMAP_OVERFLOW1, pChild->pgno);
- if( rc ) return rc;
+ rc = ptrmapPutOvfl(pChild, i);
+ if( rc!=SQLITE_OK ){
+ return rc;
}
}
}