]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Optimizations to the BTree module for a modest speed improvement. (CVS 810)
authordrh <drh@noemail.net>
Sat, 4 Jan 2003 16:48:09 +0000 (16:48 +0000)
committerdrh <drh@noemail.net>
Sat, 4 Jan 2003 16:48:09 +0000 (16:48 +0000)
FossilOrigin-Name: 39902a70417475225956704a037493515e9b08b9

manifest
manifest.uuid
src/btree.c
test/table.test

index 3d500a6c0595e82b76b457d976578e090e068849..0798b218f1f94e1383ce4f020903ea89c5572230 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Allow\sthe\srollback\sjournal\sto\sbe\sempty\sexcept\sfor\sits\sheader.\nTicket\s#212.\s(CVS\s809)
-D 2003-01-03T02:04:27
+C Optimizations\sto\sthe\sBTree\smodule\sfor\sa\smodest\sspeed\simprovement.\s(CVS\s810)
+D 2003-01-04T16:48:09
 F Makefile.in 868c17a1ae1c07603d491274cc8f86c04acf2a1e
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -18,7 +18,7 @@ F main.mk 9d13839b9697af332d788fe6e801e68da027cc5c
 F publish.sh e5b83867d14708ed58cec8cba0a4f201e969474d
 F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e
 F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
-F src/btree.c 6a2a9bb701a60df4abe2fb7047b25787c90e1ffd
+F src/btree.c 4ed13ad0c695e4fb803d106926c6fdd08a0b4d0f
 F src/btree.h 17710339f7a8f46e3c7d6d0d4648ef19c584ffda
 F src/build.c 8569ac014609add4b796260d3567a5090b90056d
 F src/delete.c aad9d4051ab46e6f6391ea5f7b8994a7c05bdd15
@@ -100,7 +100,7 @@ F test/select5.test c2a6c4a003316ee42cbbd689eebef8fdce0db2ac
 F test/select6.test efb8d0c07a440441db87db2c4ade6904e1407e85
 F test/sort.test 876b76c5a837af5bead713146c7c65f85e84fbf5
 F test/subselect.test f0fea8cf9f386d416d64d152e3c65f9116d0f50f
-F test/table.test 10508e5e53fb7971b9fa6acb29d85748e545745c
+F test/table.test 2a94f55b39008daa79b81f37aaf7be81386ca71e
 F test/tableapi.test 3c80421a889e1d106df16e5800fa787f0d2914a6
 F test/tclsqlite.test 2441ab135e5af85110326b3e3b057e7257c144e1
 F test/temptable.test 03b7bdb7d6ce2c658ad20c94b037652c6cad34e0
@@ -152,7 +152,7 @@ F www/speed.tcl a20a792738475b68756ea7a19321600f23d1d803
 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P db745e87dc26cf1a35cdcec18f4b659742e14120
-R a2eb3af8e1d5fb0a64abc7b1644d24dd
+P 1ba41bc2afab18cc295d9a45845296b46bfa57e5
+R a4125fbf39c245763f99492b33c9c8e8
 U drh
-Z 3fb10791064333a0f71d6fcfe3547d9c
+Z df8ce8a4e13ca11e4b128387a80bf533
index 5dff4bb2a84b699fadae65ee9557381e9357d619..8a7d2821720cc07d0cf98027265bffa44f041e8d 100644 (file)
@@ -1 +1 @@
-1ba41bc2afab18cc295d9a45845296b46bfa57e5
\ No newline at end of file
+39902a70417475225956704a037493515e9b08b9
\ No newline at end of file
index f34e9726269a72bdda89ffbe8f2f892db44b9929..cc178c964467db2a5de29ae4ffbce044b76e0c4e 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.76 2003/01/02 14:43:56 drh Exp $
+** $Id: btree.c,v 1.77 2003/01/04 16:48:09 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
@@ -319,11 +319,13 @@ struct MemPage {
     char aDisk[SQLITE_PAGE_SIZE];  /* Page data stored on disk */
     PageHdr hdr;                   /* Overlay page header */
   } u;
-  int isInit;                    /* True if auxiliary data is initialized */
+  u8 isInit;                     /* True if auxiliary data is initialized */
+  u8 idxShift;                   /* True if apCell[] indices have changed */
+  u8 isOverfull;                 /* Some apCell[] points outside u.aDisk[] */
   MemPage *pParent;              /* The parent of this page.  NULL for root */
+  int idxParent;                 /* Index in pParent->apCell[] of this node */
   int nFree;                     /* Number of free bytes in u.aDisk[] */
   int nCell;                     /* Number of entries on this page */
-  int isOverfull;                /* Some apCell[] points outside u.aDisk[] */
   Cell *apCell[MX_CELL+2];       /* All data entires in sorted order */
 };
 
@@ -1347,6 +1349,12 @@ static int moveToChild(BtCursor *pCur, int newPgno){
   if( rc ) return rc;
   rc = initPage(pBt, pNewPage, newPgno, pCur->pPage);
   if( rc ) return rc;
+  assert( pCur->idx>=pCur->pPage->nCell
+          || pCur->pPage->apCell[pCur->idx]->h.leftChild==SWAB32(pBt,newPgno) );
+  assert( pCur->idx<pCur->pPage->nCell
+          || pCur->pPage->u.hdr.rightChild==SWAB32(pBt,newPgno) );
+  pNewPage->idxParent = pCur->idx;
+  pCur->pPage->idxShift = 0;
   sqlitepager_unref(pCur->pPage);
   pCur->pPage = pNewPage;
   pCur->idx = 0;
@@ -1364,19 +1372,42 @@ static int moveToChild(BtCursor *pCur, int newPgno){
 static int moveToParent(BtCursor *pCur){
   Pgno oldPgno;
   MemPage *pParent;
-  int i;
+  int idxParent;
   pParent = pCur->pPage->pParent;
   if( pParent==0 ) return SQLITE_INTERNAL;
+  idxParent = pCur->pPage->idxParent;
   oldPgno = sqlitepager_pagenumber(pCur->pPage);
   sqlitepager_ref(pParent);
   sqlitepager_unref(pCur->pPage);
   pCur->pPage = pParent;
-  pCur->idx = pParent->nCell;
-  oldPgno = SWAB32(pCur->pBt, oldPgno);
-  for(i=0; i<pParent->nCell; i++){
-    if( pParent->apCell[i]->h.leftChild==oldPgno ){
-      pCur->idx = i;
-      break;
+  assert( pParent->idxShift==0 );
+  if( pParent->idxShift==0 ){
+    pCur->idx = idxParent;
+#ifndef NDEBUG  
+    /* Verify that pCur->idx is the correct index to point back to the child
+    ** page we just came from 
+    */
+    oldPgno = SWAB32(pCur->pBt, oldPgno);
+    if( pCur->idx<pParent->nCell ){
+      assert( pParent->apCell[idxParent]->h.leftChild==oldPgno );
+    }else{
+      assert( pParent->u.hdr.rightChild==oldPgno );
+    }
+#endif
+  }else{
+    /* The MemPage.idxShift flag indicates that cell indices might have 
+    ** changed since idxParent was set and hence idxParent might be out
+    ** of date.  So recompute the parent cell index by scanning all cells
+    ** and locating the one that points to the child we just came from.
+    */
+    int i;
+    pCur->idx = pParent->nCell;
+    oldPgno = SWAB32(pCur->pBt, oldPgno);
+    for(i=0; i<pParent->nCell; i++){
+      if( pParent->apCell[i]->h.leftChild==oldPgno ){
+        pCur->idx = i;
+        break;
+      }
     }
   }
   return SQLITE_OK;
@@ -1427,6 +1458,7 @@ static int moveToRightmost(BtCursor *pCur){
   int rc;
 
   while( (pgno = pCur->pPage->u.hdr.rightChild)!=0 ){
+    pCur->idx = pCur->pPage->nCell;
     rc = moveToChild(pCur, SWAB32(pCur->pBt, pgno));
     if( rc ) return rc;
   }
@@ -1536,6 +1568,7 @@ int sqliteBtreeMoveto(BtCursor *pCur, const void *pKey, int nKey, int *pRes){
       if( pRes ) *pRes = c;
       return SQLITE_OK;
     }
+    pCur->idx = lwr;
     rc = moveToChild(pCur, SWAB32(pCur->pBt, chldPg));
     if( rc ) return rc;
   }
@@ -1887,7 +1920,7 @@ static int fillInCell(
 ** given in the second argument so that MemPage.pParent holds the
 ** pointer in the third argument.
 */
-static void reparentPage(Pager *pPager, Pgno pgno, MemPage *pNewParent){
+static void reparentPage(Pager *pPager, Pgno pgno, MemPage *pNewParent,int idx){
   MemPage *pThis;
 
   if( pgno==0 ) return;
@@ -1899,6 +1932,7 @@ static void reparentPage(Pager *pPager, Pgno pgno, MemPage *pNewParent){
       pThis->pParent = pNewParent;
       if( pNewParent ) sqlitepager_ref(pNewParent);
     }
+    pThis->idxParent = idx;
     sqlitepager_unref(pThis);
   }
 }
@@ -1915,9 +1949,10 @@ static void reparentChildPages(Btree *pBt, MemPage *pPage){
   int i;
   Pager *pPager = pBt->pPager;
   for(i=0; i<pPage->nCell; i++){
-    reparentPage(pPager, SWAB32(pBt, pPage->apCell[i]->h.leftChild), pPage);
+    reparentPage(pPager, SWAB32(pBt, pPage->apCell[i]->h.leftChild), pPage, i);
   }
-  reparentPage(pPager, SWAB32(pBt, pPage->u.hdr.rightChild), pPage);
+  reparentPage(pPager, SWAB32(pBt, pPage->u.hdr.rightChild), pPage, i);
+  pPage->idxShift = 0;
 }
 
 /*
@@ -1943,6 +1978,7 @@ static void dropCell(Btree *pBt, MemPage *pPage, int idx, int sz){
     pPage->apCell[j] = pPage->apCell[j+1];
   }
   pPage->nCell--;
+  pPage->idxShift = 1;
 }
 
 /*
@@ -1975,6 +2011,7 @@ static void insertCell(Btree *pBt, MemPage *pPage, int i, Cell *pCell, int sz){
     memcpy(&pPage->u.aDisk[idx], pCell, sz);
     pPage->apCell[i] = (Cell*)&pPage->u.aDisk[idx];
   }
+  pPage->idxShift = 1;
 }
 
 /*
@@ -2161,6 +2198,7 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
     assert( sqlitepager_iswriteable(pChild) );
     copyPage(pChild, pPage);
     pChild->pParent = pPage;
+    pChild->idxParent = pChild->nCell;
     sqlitepager_ref(pPage);
     pChild->isOverfull = 1;
     if( pCur && pCur->pPage==pPage ){
@@ -2195,9 +2233,8 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
   if( idx<0 && pParent->u.hdr.rightChild==swabPgno ){
     idx = pParent->nCell;
   }
-  if( idx<0 ){
-    return SQLITE_CORRUPT;
-  }
+  assert( idx>=0 );
+  /* assert( pParent->idxShift || idx==pPage->idxParent ); */
 
   /*
   ** Initialize variables so that it will be safe to jump
@@ -2235,6 +2272,7 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
     if( rc ) goto balance_cleanup;
     rc = initPage(pBt, apOld[i], pgnoOld[i], pParent);
     if( rc ) goto balance_cleanup;
+    apOld[i]->idxParent = k;
     nOld++;
   }
 
index 8bed034a9b342d38c869e733e5eb81b80d02eef1..adad1567c54b0126db7e7edaaf94d89bffbdcc57 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the CREATE TABLE statement.
 #
-# $Id: table.test,v 1.20 2002/08/31 18:53:09 drh Exp $
+# $Id: table.test,v 1.21 2003/01/04 16:48:10 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -217,9 +217,9 @@ set r {}
 for {set i 1} {$i<=100} {incr i 2} {
   lappend r [format test%03d $i]
 }
-#execsql {--vdbe-trace-on--}
 do_test table-4.2 {
   for {set i 2} {$i<=100} {incr i 2} {
+    # if {$i==38} {execsql {pragma vdbe_trace=on}}
     set sql "DROP TABLE [format TEST%03d $i]"
     execsql $sql
   }