-C Another\soptimization\sto\sthe\sbtree\slogic.\s(CVS\s811)
-D 2003-01-04T18:53:28
+C Parameterize\sthe\snumber\sof\sadjacent\spages\sthat\sparticipate\sin\sthe\sbalancing\nalgorithm\sin\sthe\sBTree.\s\sBut\sleave\sthe\ssetting\sat\sthe\scurrent\svalue\sof\s3.\s(CVS\s812)
+D 2003-01-04T19:44:08
F Makefile.in 868c17a1ae1c07603d491274cc8f86c04acf2a1e
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F publish.sh e5b83867d14708ed58cec8cba0a4f201e969474d
F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e
F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
-F src/btree.c 9ae3232125d54e0f4c73ae88af1f4556e15440e9
+F src/btree.c 65dfa86fc2a9eded02fc011c368d20174fba10d1
F src/btree.h 17710339f7a8f46e3c7d6d0d4648ef19c584ffda
F src/build.c 8569ac014609add4b796260d3567a5090b90056d
F src/delete.c aad9d4051ab46e6f6391ea5f7b8994a7c05bdd15
F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P 39902a70417475225956704a037493515e9b08b9
-R 5307d3e389db7bcbbe208e92a667a5a5
+P 03d20673616cae0dca524fd04557798a98fb7069
+R 131375a6bd5b4a8f3f85a8c7c672f995
U drh
-Z 5237255ce20b25abc6c29c72daee1d77
+Z c7e9682e375704261f3906f005af16af
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.78 2003/01/04 18:53:28 drh Exp $
+** $Id: btree.c,v 1.79 2003/01/04 19:44:08 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
}
}
+/*
+** The following parameters determine how many adjacent pages get involved
+** in a balancing operation. NN is the number of neighbors on either side
+** of the page that participate in the balancing operation. NB is the
+** total number of pages that participate, including the target page and
+** NN neighbors on either side.
+**
+** The minimum value of NN is 1 (of course). Increasing NN above 1
+** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance
+** in exchange for a larger degradation in INSERT and UPDATE performance.
+** The value of NN appears to give the best results overall.
+*/
+#define NN 1 /* Number of neighbors on either side of pPage */
+#define NB (NN*2+1) /* Total pages involved in the balance */
+
/*
** This routine redistributes Cells on pPage and up to two siblings
** of pPage so that all pages have about the same amount of free space.
*/
static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
MemPage *pParent; /* The parent of pPage */
- MemPage *apOld[3]; /* pPage and up to two siblings */
- Pgno pgnoOld[3]; /* Page numbers for each page in apOld[] */
- MemPage *apNew[4]; /* pPage and up to 3 siblings after balancing */
- Pgno pgnoNew[4]; /* Page numbers for each page in apNew[] */
- int idxDiv[3]; /* Indices of divider cells in pParent */
- Cell *apDiv[3]; /* Divider cells in pParent */
int nCell; /* Number of cells in apCell[] */
int nOld; /* Number of pages in apOld[] */
int nNew; /* Number of pages in apNew[] */
int iCur; /* apCell[iCur] is the cell of the cursor */
MemPage *pOldCurPage; /* The cursor originally points to this page */
int subtotal; /* Subtotal of bytes in cells on one page */
- int cntNew[4]; /* Index in apCell[] of cell after i-th page */
- int szNew[4]; /* Combined size of cells place on i-th page */
MemPage *extraUnref = 0; /* A page that needs to be unref-ed */
- Cell *apCell[MX_CELL*3+5]; /* All cells from pages being balanceed */
- int szCell[MX_CELL*3+5]; /* Local size of all cells */
- Cell aTemp[2]; /* Temporary holding area for apDiv[] */
- MemPage aOld[3]; /* Temporary copies of pPage and its siblings */
+ MemPage *apOld[NB]; /* pPage and up to two siblings */
+ Pgno pgnoOld[NB]; /* Page numbers for each page in apOld[] */
+ MemPage *apNew[NB+1]; /* pPage and up to NB siblings after balancing */
+ Pgno pgnoNew[NB+1]; /* Page numbers for each page in apNew[] */
+ int idxDiv[NB]; /* Indices of divider cells in pParent */
+ Cell *apDiv[NB]; /* Divider cells in pParent */
+ Cell aTemp[NB]; /* Temporary holding area for apDiv[] */
+ int cntNew[NB+1]; /* Index in apCell[] of cell after i-th page */
+ int szNew[NB+1]; /* Combined size of cells place on i-th page */
+ MemPage aOld[NB]; /* Temporary copies of pPage and its siblings */
+ Cell *apCell[(MX_CELL+2)*NB]; /* All cells from pages being balanced */
+ int szCell[(MX_CELL+2)*NB]; /* Local size of all cells */
/*
** Return without doing any work if pPage is neither overfull nor
/*
** Find sibling pages to pPage and the Cells in pParent that divide
- ** the siblings. An attempt is made to find one sibling on either
- ** side of pPage. Both siblings are taken from one side, however, if
- ** pPage is either the first or last child of its parent. If pParent
- ** has 3 or fewer children then all children of pParent are taken.
+ ** the siblings. An attempt is made to find NN siblings on either
+ ** side of pPage. More siblings are taken from one side, however, if
+ ** pPage there are fewer than NN siblings on the other side. If pParent
+ ** has NB or fewer children then all children of pParent are taken.
*/
- if( idx==pParent->nCell ){
- nxDiv = idx - 2;
- }else{
- nxDiv = idx - 1;
+ nxDiv = idx - NN;
+ if( nxDiv + NB > pParent->nCell ){
+ nxDiv = pParent->nCell - NB + 1;
+ }
+ if( nxDiv<0 ){
+ nxDiv = 0;
}
- if( nxDiv<0 ) nxDiv = 0;
nDiv = 0;
- for(i=0, k=nxDiv; i<3; i++, k++){
+ for(i=0, k=nxDiv; i<NB; i++, k++){
if( k<pParent->nCell ){
idxDiv[i] = k;
apDiv[i] = pParent->apCell[k];
** from the disk more rapidly.
**
** An O(n^2) insertion sort algorithm is used, but since
- ** n is never more than 3, that should not be a problem.
+ ** n is never more than NB (a small constant), that should
+ ** not be a problem.
**
- ** This one optimization makes the database about 25%
- ** faster for large insertions and deletions.
+ ** When NB==3, this one optimization makes the database
+ ** about 25% faster for large insertions and deletions.
*/
for(i=0; i<k-1; i++){
int minV = pgnoNew[i];