]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Experimental patch to balance() (use -DSQLITE_BALANCE_QUICK). (CVS 2211)
authordanielk1977 <danielk1977@noemail.net>
Fri, 14 Jan 2005 13:50:11 +0000 (13:50 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Fri, 14 Jan 2005 13:50:11 +0000 (13:50 +0000)
FossilOrigin-Name: c550d80c25ec88fceb20acabd00c21faa2d552f5

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

index 0c00b8c4ac4d3acf387f328132c12ffca420901f..76222c934031bfe5eaf8008a32df84b5620f9055 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Improved\stest\scoverage\son\sinsert.c.\s(CVS\s2210)
-D 2005-01-14T01:22:01
+C Experimental\spatch\sto\sbalance()\s(use\s-DSQLITE_BALANCE_QUICK).\s(CVS\s2211)
+D 2005-01-14T13:50:12
 F Makefile.in 6ce51dde6a8fe82fc12f20dec750572f6a19f56a
 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
 F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
@@ -29,7 +29,7 @@ F sqlite3.def dbaeb20c153e1d366e8f421b55a573f5dfc00863
 F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
 F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689
 F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea
-F src/btree.c bd2fd7fed9cc1ec84e70fe9f01dfcb474b53bbe5
+F src/btree.c 1a351402dbbf5cc5f8ecf1b338f8da20c073c46e
 F src/btree.h 74d19cf40ab49fd69abe9e4e12a6c321ad86c497
 F src/build.c af1296e8a21a406b4f4c4f1e1365e075071219f3
 F src/cursor.c f883813759742068890b1f699335872bfa8fdf41
@@ -139,7 +139,7 @@ F test/insert2.test 0bb50ff999e35a21549d8ee5dc44db8ac24d31a7
 F test/insert3.test 421f6017ad268fcdba0b8ab56a2dff7265d3cf23
 F test/interrupt.test 5b4d8389e6cf2d01b94f87cfd02d9df1073bfb2d
 F test/intpkey.test b57cf5236fde1bd8cbc1388fa0c91908f6fd9194
-F test/ioerr.test 259bef101273a8e7b16d004018ee5a7873a26889
+F test/ioerr.test fe51bacd7ffb83b9a0b70eceee3608dfd36371f6
 F test/join.test ea8c77b9fbc377fe553cdb5ce5f1bd72021dca5d
 F test/join2.test c97e4c5aa65dea462145529e58212a709b4722b8
 F test/join3.test 67dc0d7c8dab3fff25796d0f3c3fd9c999aeded3
@@ -269,7 +269,7 @@ F www/tclsqlite.tcl e73f8f8e5f20e8277619433f7970060ab01088fc
 F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618
 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
 F www/whentouse.tcl c3b50d3ac31c54be2a1af9b488a89d22f1e6e746
-P 6e905270a933fd4c99f6db6707ed79166f6484ee
-R b0f921b0cc4246465f13a208b372d988
-U drh
-Z 0f466f7cb587c20134aa5d2e4fe7cd6a
+P c772f75166d55192132e732e8a0ddda5926f00f2
+R a2176157e002acaa6ba57b3b04bf35d8
+U danielk1977
+Z be978985848951cc4077641a9406e5b8
index 64846c6ed12aa823fef7eb72074d2652ab0e7766..0a9619bf9628c5f21ff1e3732b7e0a3aae3da236 100644 (file)
@@ -1 +1 @@
-c772f75166d55192132e732e8a0ddda5926f00f2
\ No newline at end of file
+c550d80c25ec88fceb20acabd00c21faa2d552f5
\ No newline at end of file
index 6c9c98b5e4f6de7cf736691cf46f254ac6955435..c21e2e19098d7a55d0543379fa2b21d782dd3d5a 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.231 2005/01/12 07:15:05 danielk1977 Exp $
+** $Id: btree.c,v 1.232 2005/01/14 13:50:12 danielk1977 Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
@@ -3556,7 +3556,57 @@ static void assemblePage(
 #define NB (NN*2+1)      /* Total pages involved in the balance */
 
 /* Forward reference */
-static int balance(MemPage*);
+static int balance(MemPage*, int);
+
+static int balance_quick(MemPage *pPage, MemPage *pParent){
+  int rc;
+  MemPage *pNew;
+  Pgno pgnoNew;
+  u8 *pCell;
+  int szCell;
+  CellInfo info;
+
+  u8 parentCell[64];              /* How big should this be? */
+  int parentIdx = pParent->nCell;
+  int parentSize;
+
+  /* Allocate a new page. Insert the overflow cell from pPage
+  ** into it. Then remove the overflow cell from pPage.
+  */
+  rc = allocatePage(pPage->pBt, &pNew, &pgnoNew, 0, 0);
+  if( rc!=SQLITE_OK ){
+    return rc;
+  }
+  pCell = pPage->aOvfl[0].pCell;
+  szCell = cellSizePtr(pPage, pCell);
+  zeroPage(pNew, pPage->aData[0]);
+  assemblePage(pNew, 1, &pCell, &szCell);
+  pPage->nOverflow = 0;
+
+  /* pPage is currently the right-child of pParent. Change this
+  ** so that the right-child is the new page allocated above and
+  ** pPage is the next-to-right child. Then balance() the parent
+  ** page, in case it is now overfull.
+  */
+  parseCellPtr(pPage, findCell(pPage, pPage->nCell-1), &info);
+  rc = fillInCell(pParent, parentCell, 0, info.nKey, 0, 0, &parentSize);
+  if( rc!=SQLITE_OK ){
+    return SQLITE_OK;
+  }
+  assert( parentSize<64 );
+  rc = insertCell(pParent, parentIdx, parentCell, parentSize, 0, 4);
+  if( rc!=SQLITE_OK ){
+    return SQLITE_OK;
+  }
+  put4byte(findOverflowCell(pParent,parentIdx), pPage->pgno);
+  put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew);
+
+  pNew->pParent = pParent;
+  sqlite3pager_ref(pParent->aData);
+
+  releasePage(pNew);
+  return balance(pParent, 0);
+}
 
 /*
 ** This routine redistributes Cells on pPage and up to NN*2 siblings
@@ -3630,6 +3680,18 @@ static int balance_nonroot(MemPage *pPage){
   assert( pParent );
   TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
 
+#ifdef SQLITE_BALANCE_QUICK
+  if( pPage->leaf &&
+      pPage->intKey &&
+      pPage->leafData &&
+      pPage->nOverflow==1 &&
+      pPage->aOvfl[0].idx==pPage->nCell &&
+      get4byte(&pParent->aData[pParent->hdrOffset+8])==pPage->pgno
+  ){
+    return balance_quick(pPage, pParent);
+  }
+#endif
+
   /*
   ** Allocate space for memory structures
   */
@@ -3995,7 +4057,7 @@ static int balance_nonroot(MemPage *pPage){
   assert( pParent->isInit );
   /* assert( pPage->isInit ); // No! pPage might have been added to freelist */
   /* pageIntegrity(pPage);    // No! pPage might have been added to freelist */ 
-  rc = balance(pParent);
+  rc = balance(pParent, 0);
   
   /*
   ** Cleanup before returning.
@@ -4154,7 +4216,7 @@ static int balance_deeper(MemPage *pPage){
 ** Decide if the page pPage needs to be balanced.  If balancing is
 ** required, call the appropriate balancing routine.
 */
-static int balance(MemPage *pPage){
+static int balance(MemPage *pPage, int insert){
   int rc = SQLITE_OK;
   if( pPage->pParent==0 ){
     if( pPage->nOverflow>0 ){
@@ -4164,7 +4226,8 @@ static int balance(MemPage *pPage){
       rc = balance_shallower(pPage);
     }
   }else{
-    if( pPage->nOverflow>0 || pPage->nFree>pPage->pBt->usableSize*2/3 ){
+    if( pPage->nOverflow>0 || 
+        (!insert && pPage->nFree>pPage->pBt->usableSize*2/3) ){
       rc = balance_nonroot(pPage);
     }
   }
@@ -4268,7 +4331,7 @@ int sqlite3BtreeInsert(
   }
   rc = insertCell(pPage, pCur->idx, newCell, szNew, 0, 0);
   if( rc!=SQLITE_OK ) goto end_insert;
-  rc = balance(pPage);
+  rc = balance(pPage, 1);
   /* sqlite3BtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */
   /* fflush(stdout); */
   if( rc==SQLITE_OK ){
@@ -4354,17 +4417,17 @@ int sqlite3BtreeDelete(BtCursor *pCur){
     rc = insertCell(pPage, pCur->idx, pNext-4, szNext+4, tempCell, 0);
     if( rc!=SQLITE_OK ) return rc;
     put4byte(findOverflowCell(pPage, pCur->idx), pgnoChild);
-    rc = balance(pPage);
+    rc = balance(pPage, 0);
     sqliteFree(tempCell);
     if( rc ) return rc;
     dropCell(leafCur.pPage, leafCur.idx, szNext);
-    rc = balance(leafCur.pPage);
+    rc = balance(leafCur.pPage, 0);
     releaseTempCursor(&leafCur);
   }else{
     TRACE(("DELETE: table=%d delete from leaf %d\n",
        pCur->pgnoRoot, pPage->pgno));
     dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell));
-    rc = balance(pPage);
+    rc = balance(pPage, 0);
   }
   moveToRoot(pCur);
   return rc;
@@ -5281,6 +5344,11 @@ char *sqlite3BtreeIntegrityCheck(Btree *pBt, int *aRoot, int nRoot){
     return 0;
   }
   sCheck.anRef = sqliteMallocRaw( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) );
+  if( !sCheck.anRef ){
+    unlockBtreeIfUnused(pBt);
+    return sqlite3MPrintf("Unable to malloc %d bytes", 
+        (sCheck.nPage+1)*sizeof(sCheck.anRef[0]));
+  }
   for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; }
   i = PENDING_BYTE_PAGE(pBt);
   if( i<=sCheck.nPage ){
index 6d277d07cb748858c855243ba368e86b6e242820..489643c8ca0ef45be3a1da19af26b9fe3f619dfe 100644 (file)
@@ -15,7 +15,7 @@
 # The tests in this file use special facilities that are only
 # available in the SQLite test fixture.
 #
-# $Id: ioerr.test,v 1.12 2005/01/13 11:07:54 danielk1977 Exp $
+# $Id: ioerr.test,v 1.13 2005/01/14 13:50:13 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -232,7 +232,7 @@ do_ioerr_test 5 -sqlprep {
 
 # Test IO errors when replaying two hot journals from a 2-file 
 # transaction. This test only runs on UNIX.
-if {$tcl_platform(platform)=="unix"} {
+if {$tcl_platform(platform)=="unix" && [file exists ./crashtest]} {
   do_ioerr_test 6 -tclprep {
     set rc [crashsql 2 test2.db-journal {
       ATTACH 'test2.db' as aux;