-C Make\sthe\sBTree\sbalance()\sroutine\sa\slittle\sfaster\sby\sreusing\sdatabase\r\npages\slocally\srather\sthan\sfreeing\sand\sreallocating\sthem.\s(CVS\s666)
-D 2002-07-08T02:16:38
+C In\sthe\sBTree\ssubsystem,\swhen\susing\spages\sfrom\sthe\sfreelist,\sattempt\sto\sselect\npages\sclose\sto\srelated\spages\sin\sorder\sto\skeep\sdata\sstructures\snear\seach\sother\nin\sthe\sdatabase\sfile.\s\sThis\simproves\saccess\sspeed\sin\ssome\scircumstances.\s(CVS\s667)
+D 2002-07-08T10:59:51
F Makefile.in 6291a33b87d2a395aafd7646ee1ed562c6f2c28c
F Makefile.template 4e11752e0b5c7a043ca50af4296ec562857ba495
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e
F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
-F src/btree.c ce999ee3f5c6130aa12529ba4f510679d0a07faa
+F src/btree.c db8cd1bd46cd30a1763c3cc80602571d1b30a329
F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3
F src/build.c ea4a3bc15d6338294e68100f642edf48e4082403
F src/delete.c 215492ffcea4262a993e55f3c4a67dc9fea4da9c
F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P 111c78e6835306fcd8b6d22b9ae68dfb9ab4febe
-R 66eadf0358149489c17da262453c92f0
+P 3c2dea4310af491d6cb09856d4bc5236d6dc44ac
+R 6fce7034f8d829ff998a11d6ed601ee8
U drh
-Z 70877f6880980e12b35ccd8168df5635
+Z 0f3c77c73454501b08d2d78dacfaba6f
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.66 2002/07/08 02:16:38 drh Exp $
+** $Id: btree.c,v 1.67 2002/07/08 10:59:51 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
** SQLITE_OK is returned on success. Any other return value indicates
** an error. *ppPage and *pPgno are undefined in the event of an error.
** Do not invoke sqlitepager_unref() on *ppPage if an error is returned.
+**
+** If the "near" parameter is not 0, then a (feeble) effort is made to
+** locate a page close to the page number "near". This can be used in an
+** attempt to keep related pages close to each other in the database file,
+** which in turn can make database access faster.
*/
-static int allocatePage(Btree *pBt, MemPage **ppPage, Pgno *pPgno){
+static int allocatePage(Btree *pBt, MemPage **ppPage, Pgno *pPgno, Pgno near){
PageOne *pPage1 = pBt->page1;
int rc;
if( pPage1->freeList ){
pPage1->freeList = pOvfl->iNext;
*ppPage = (MemPage*)pOvfl;
}else{
+ int closest;
+ if( pInfo->nFree>1 && near>0 ){
+ int i, dist;
+ closest = 0;
+ dist = pInfo->aFree[0] - near;
+ if( dist<0 ) dist = -dist;
+ for(i=1; i<pInfo->nFree; i++){
+ int d2 = pInfo->aFree[i] - near;
+ if( d2<0 ) d2 = -d2;
+ if( d2<dist ) closest = i;
+ }
+ }else{
+ closest = 0;
+ }
pInfo->nFree--;
- *pPgno = pInfo->aFree[pInfo->nFree];
+ *pPgno = pInfo->aFree[closest];
+ pInfo->aFree[closest] = pInfo->aFree[pInfo->nFree];
rc = sqlitepager_get(pBt->pPager, *pPgno, (void**)ppPage);
sqlitepager_unref(pOvfl);
if( rc==SQLITE_OK ){
int nPayload;
const char *pPayload;
char *pSpace;
+ Pgno near = 0;
pCell->h.leftChild = 0;
pCell->h.nKey = nKey & 0xffff;
pPrior = 0;
while( nPayload>0 ){
if( spaceLeft==0 ){
- rc = allocatePage(pBt, (MemPage**)&pOvfl, pNext);
+ rc = allocatePage(pBt, (MemPage**)&pOvfl, pNext, near);
if( rc ){
*pNext = 0;
+ }else{
+ near = *pNext;
}
if( pPrior ) sqlitepager_unref(pPrior);
if( rc ){
*/
rc = sqlitepager_write(pPage);
if( rc ) return rc;
- rc = allocatePage(pBt, &pChild, &pgnoChild);
+ rc = allocatePage(pBt, &pChild, &pgnoChild, sqlitepager_pagenumber(pPage));
if( rc ) return rc;
assert( sqlitepager_iswriteable(pChild) );
copyPage(pChild, pPage);
apOld[i] = 0;
sqlitepager_write(apNew[i]);
}else{
- rc = allocatePage(pBt, &apNew[i], &pgnoNew[i]);
+ rc = allocatePage(pBt, &apNew[i], &pgnoNew[i], pgnoNew[i-1]);
if( rc ) goto balance_cleanup;
}
nNew++;
if( pBt->readOnly ){
return SQLITE_READONLY;
}
- rc = allocatePage(pBt, &pRoot, &pgnoRoot);
+ rc = allocatePage(pBt, &pRoot, &pgnoRoot, 0);
if( rc ) return rc;
assert( sqlitepager_iswriteable(pRoot) );
zeroPage(pRoot);