]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
A small performance improvement in freeSpace() by special-casing the
authordrh <drh@noemail.net>
Wed, 20 Aug 2014 18:43:44 +0000 (18:43 +0000)
committerdrh <drh@noemail.net>
Wed, 20 Aug 2014 18:43:44 +0000 (18:43 +0000)
relatively common case of an empty freelist.

FossilOrigin-Name: 49f44d355ff70744e4951baca2481c7c2b6c02b3

manifest
manifest.uuid
src/btree.c

index 4fe8e5ec20900f41a2c2217940e483d78201ce14..0e557551980f02d8ed62e42403a240154dc49de8 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Reimplement\sthe\sfreeSpace()\sroutine\sin\sbtree.c\sso\sthat\sit\sruns\sfaster.
-D 2014-08-20T17:56:27.585
+C A\ssmall\sperformance\simprovement\sin\sfreeSpace()\sby\sspecial-casing\sthe\nrelatively\scommon\scase\sof\san\sempty\sfreelist.
+D 2014-08-20T18:43:44.510
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -167,7 +167,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
 F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
-F src/btree.c fe2d11c8c0d99e324614141ad012b37d0601cf59
+F src/btree.c 4195fed5741b4dbcc9831b623aec487258f3e62d
 F src/btree.h 4245a349bfe09611d7ff887dbc3a80cee8b7955a
 F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3
 F src/build.c 5abf794fe8a605f2005b422e98a3cedad9b9ef5b
@@ -1186,7 +1186,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 7e63089a191f29aefde05e89bb612f3036cfa034
-R cbff1ae81d05ca3b78b420deaaa6083f
+P fe4fd014b42b7b158ca968f1535b5636c67769f6
+R 865eceb09aea170bb70d44b771b85e6e
 U drh
-Z d684bbbc1bfe7cdee532398c2232ddf8
+Z 0631afdcc5729e41fc50a75336710200
index 238682a66defe8275414d860102716f69286fc60..2bb2527d3056d4502a8b0711aec3f6d6b353da2f 100644 (file)
@@ -1 +1 @@
-fe4fd014b42b7b158ca968f1535b5636c67769f6
\ No newline at end of file
+49f44d355ff70744e4951baca2481c7c2b6c02b3
\ No newline at end of file
index c10e2f1c3203d832dc51b94fe0d69d49d2ef1ebd..56718b69d61292c9cfe5192ad4cba9433bc1fe46 100644 (file)
@@ -1330,47 +1330,51 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
   */
   hdr = pPage->hdrOffset;
   iPtr = hdr + 1;
-  while( (iFreeBlk = get2byte(&data[iPtr]))>0 && iFreeBlk<iStart ){
-    if( iFreeBlk<iPtr+4 ) return SQLITE_CORRUPT_BKPT;
-    iPtr = iFreeBlk;
-  }
-  if( iFreeBlk>iLast ) return SQLITE_CORRUPT_BKPT;
-  assert( iFreeBlk>iPtr || iFreeBlk==0 );
-
-  /* At this point:
-  **    iFreeBlk:   First freeblock after iStart, or zero if none
-  **    iPtr:       The address of a pointer iFreeBlk
-  **
-  ** Check to see if iFreeBlk should be coalesced onto the end of iStart.
-  */
-  if( iFreeBlk && iEnd+3>=iFreeBlk ){
-    nFrag = iFreeBlk - iEnd;
-    if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_BKPT;
-    iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
-    iSize = iEnd - iStart;
-    iFreeBlk = get2byte(&data[iFreeBlk]);
-  }
-
-  /* If iPtr is another freeblock (that is, if iPtr is not the freelist pointer
-  ** in the page header) then check to see if iStart should be coalesced 
-  ** onto the end of iPtr.
-  */
-  if( iPtr>hdr+1 ){
-    int iPtrEnd = iPtr + get2byte(&data[iPtr+2]);
-    if( iPtrEnd+3>=iStart ){
-      if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT;
-      nFrag += iStart - iPtrEnd;
-      iSize = iEnd - iPtr;
-      iStart = iPtr;
+  if( data[iPtr+1]==0 && data[iPtr]==0 ){
+    iFreeBlk = 0;  /* Shortcut for the case when the freelist is empty */
+  }else{
+    while( (iFreeBlk = get2byte(&data[iPtr]))>0 && iFreeBlk<iStart ){
+      if( iFreeBlk<iPtr+4 ) return SQLITE_CORRUPT_BKPT;
+      iPtr = iFreeBlk;
     }
+    if( iFreeBlk>iLast ) return SQLITE_CORRUPT_BKPT;
+    assert( iFreeBlk>iPtr || iFreeBlk==0 );
+  
+    /* At this point:
+    **    iFreeBlk:   First freeblock after iStart, or zero if none
+    **    iPtr:       The address of a pointer iFreeBlk
+    **
+    ** Check to see if iFreeBlk should be coalesced onto the end of iStart.
+    */
+    if( iFreeBlk && iEnd+3>=iFreeBlk ){
+      nFrag = iFreeBlk - iEnd;
+      if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_BKPT;
+      iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
+      iSize = iEnd - iStart;
+      iFreeBlk = get2byte(&data[iFreeBlk]);
+    }
+  
+    /* If iPtr is another freeblock (that is, if iPtr is not the freelist pointer
+    ** in the page header) then check to see if iStart should be coalesced 
+    ** onto the end of iPtr.
+    */
+    if( iPtr>hdr+1 ){
+      int iPtrEnd = iPtr + get2byte(&data[iPtr+2]);
+      if( iPtrEnd+3>=iStart ){
+        if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT;
+        nFrag += iStart - iPtrEnd;
+        iSize = iEnd - iPtr;
+        iStart = iPtr;
+      }
+    }
+    if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_BKPT;
+    data[hdr+7] -= nFrag;
   }
-  if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_BKPT;
-
-  data[hdr+7] -= nFrag;
-  if( iPtr==hdr+1 && iStart==get2byte(&data[hdr+5]) ){
+  if( iStart==get2byte(&data[hdr+5]) ){
     /* The new freeblock is at the beginning of the cell content area,
     ** so just extend the cell content area rather than create another
     ** freelist entry */
+    if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_BKPT;
     put2byte(&data[hdr+1], iFreeBlk);
     put2byte(&data[hdr+5], iEnd);
   }else{