]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
In the BTree subsystem, when using pages from the freelist, attempt to select
authordrh <drh@noemail.net>
Mon, 8 Jul 2002 10:59:50 +0000 (10:59 +0000)
committerdrh <drh@noemail.net>
Mon, 8 Jul 2002 10:59:50 +0000 (10:59 +0000)
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
manifest.uuid
src/btree.c

index e50db17c1a1b2016515f47021951bc632095fc2a..49bad20a914bcf084be6a62c01b2cd3c200cc7e9 100644 (file)
--- 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
index 0f38434159b08a1573a2e35d72f11cd1952acd04..4359c88e450d407b753f63efe8fc8ff54f7ce1ef 100644 (file)
@@ -1 +1 @@
-3c2dea4310af491d6cb09856d4bc5236d6dc44ac
\ No newline at end of file
+fd7e41f0eed80fb1c7e18eb84834ec3cea74a649
\ No newline at end of file
index 9dfb46dd9fb82e7796b21e413f5aee9ee8651207..253ad0e5854edbe3214a877fbd388c87f9682168 100644 (file)
@@ -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; 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 ){
@@ -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);