From bea00b9a2b943737b40ef23bee5eafa79e36a86b Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 8 Jul 2002 10:59:50 +0000 Subject: [PATCH] In the BTree subsystem, when using pages from the freelist, attempt to select pages close to related pages in order to keep data structures near each other in the database file. This improves access speed in some circumstances. (CVS 667) FossilOrigin-Name: fd7e41f0eed80fb1c7e18eb84834ec3cea74a649 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 37 ++++++++++++++++++++++++++++++------- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index e50db17c1a..49bad20a91 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 @@ -18,7 +18,7 @@ F publish.sh 1a04b9aa0d9c9661e338268343476ed0851c5778 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 @@ -140,7 +140,7 @@ F www/speed.tcl da8afcc1d3ccc5696cfb388a68982bc3d9f7f00f 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 diff --git a/manifest.uuid b/manifest.uuid index 0f38434159..4359c88e45 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3c2dea4310af491d6cb09856d4bc5236d6dc44ac \ No newline at end of file +fd7e41f0eed80fb1c7e18eb84834ec3cea74a649 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 9dfb46dd9f..253ad0e585 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.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 @@ -1509,8 +1509,13 @@ int sqliteBtreeNext(BtCursor *pCur, int *pRes){ ** 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 ){ @@ -1533,8 +1538,23 @@ static int allocatePage(Btree *pBt, MemPage **ppPage, Pgno *pPgno){ 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; inFree; i++){ + int d2 = pInfo->aFree[i] - near; + if( d2<0 ) d2 = -d2; + if( d2nFree--; - *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 ){ @@ -1660,6 +1680,7 @@ static int fillInCell( int nPayload; const char *pPayload; char *pSpace; + Pgno near = 0; pCell->h.leftChild = 0; pCell->h.nKey = nKey & 0xffff; @@ -1677,9 +1698,11 @@ static int fillInCell( 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 ){ @@ -1986,7 +2009,7 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){ */ 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); @@ -2171,7 +2194,7 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){ 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++; @@ -2455,7 +2478,7 @@ int sqliteBtreeCreateTable(Btree *pBt, int *piTable){ 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);