]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Another performance tweak: Split the sqlite3BtreeCursorHasMoved() routine
authordrh <drh@noemail.net>
Fri, 22 Aug 2014 23:33:03 +0000 (23:33 +0000)
committerdrh <drh@noemail.net>
Fri, 22 Aug 2014 23:33:03 +0000 (23:33 +0000)
into two with the second routine named sqlite3BtreeCursorRestore().  The first
now only reports whether or not the cursor has moved and the second tries to
restore the cursor.  This allows the sqlite3VdbeCursorMoveto() routine to be
refactored to avoid stack pointer movements, for a noticable performance gain.

FossilOrigin-Name: ce123b5c592556a8cd38b01fcc91ba76231d3098

manifest
manifest.uuid
src/btree.c
src/btree.h
src/vdbeaux.c

index a0fd1d8b2ef42f4ec1c4e5e1af95e4b4ef7304c0..98cd57119ed7acbdd226379054d9a47c930d5b68 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Factor\sthe\ssaveAllCursors()\sroutine\sof\sbtree.c\sinto\stwo\sseparate\sroutines,\nfor\sa\snoticable\sperformance\simprovement.
-D 2014-08-22T22:26:07.834
+C Another\sperformance\stweak:\sSplit\sthe\ssqlite3BtreeCursorHasMoved()\sroutine\s\ninto\stwo\swith\sthe\ssecond\sroutine\snamed\ssqlite3BtreeCursorRestore().\s\sThe\sfirst\nnow\sonly\sreports\swhether\sor\snot\sthe\scursor\shas\smoved\sand\sthe\ssecond\stries\sto\nrestore\sthe\scursor.\s\sThis\sallows\sthe\ssqlite3VdbeCursorMoveto()\sroutine\sto\sbe\nrefactored\sto\savoid\sstack\spointer\smovements,\sfor\sa\snoticable\sperformance\sgain.
+D 2014-08-22T23:33:03.189
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -168,8 +168,8 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
 F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e
 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
 F src/btmutex.c ec9d3f1295dafeb278c3830211cc5584132468f4
-F src/btree.c 776885dfef3033af7e8eabbf004481f219870a1d
-F src/btree.h 4245a349bfe09611d7ff887dbc3a80cee8b7955a
+F src/btree.c c4b4e1c9524ba7b7dab840e6f8b29e2379a3bdd2
+F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8
 F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3
 F src/build.c 058e3aadb1376521ff291735237edf4c10f438fb
 F src/callback.c b97d0695ffcf6a8710ee445ffe56ee387d4d8a6f
@@ -288,7 +288,7 @@ F src/vdbe.c f7f4066e4d6e3858878d76ce9288ea603e12ddf6
 F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8
 F src/vdbeInt.h f5513f2b5ac1e2c5128996c7ea23add256a301df
 F src/vdbeapi.c 49b8d2943d02d276b4efef114578251a3277f47d
-F src/vdbeaux.c f7fdc59e2eefa6fc4ba7324b03ea6f8f66e98d62
+F src/vdbeaux.c dba006f67c9fd1b1d07ee7fb0fb38aa1905161d1
 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4
 F src/vdbemem.c 4a64659ed8e4c3b18a9238e038145ab1bdcd146f
 F src/vdbesort.c f7f5563bf7d4695ca8f3203f3bf9de96d04ed0b3
@@ -1188,7 +1188,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 8914530644f938a7a98e25ea1fb0bca1f9d79101
-R 036983fb95199f1ba06f1397f389a453
+P 3eb084390382c108e9b0ff0b29dede58ebb149bc
+R 356d2e894dc7576ad768e53fab77ee5b
 U drh
-Z 9ea20fed62648c22294e9e322338cabb
+Z 78a9bc2b7c59c5e05ea01f499ba8646b
index 334a3ae4c0faf2ac99ef42bd5b58388508367bfb..af6d676ce0e9752b0fdd38310c8c32460842c257 100644 (file)
@@ -1 +1 @@
-3eb084390382c108e9b0ff0b29dede58ebb149bc
\ No newline at end of file
+ce123b5c592556a8cd38b01fcc91ba76231d3098
\ No newline at end of file
index 6da3715e30d0839f5437f947c4f26a9e3b98bed3..23de31db0743e67e0fceb3886a10ba01f73ce28d 100644 (file)
@@ -762,37 +762,48 @@ static int btreeRestoreCursorPosition(BtCursor *pCur){
          SQLITE_OK)
 
 /*
-** Determine whether or not a cursor has moved from the position it
-** was last placed at.  Cursors can move when the row they are pointing
-** at is deleted out from under them.
-**
-** This routine returns an error code if something goes wrong.  The
-** integer *pHasMoved is set as follows:
-**
-**    0:   The cursor is unchanged
-**    1:   The cursor is still pointing at the same row, but the pointers
-**         returned by sqlite3BtreeKeyFetch() or sqlite3BtreeDataFetch()
-**         might now be invalid because of a balance() or other change to the
-**         b-tree.
-**    2:   The cursor is no longer pointing to the row.  The row might have
-**         been deleted out from under the cursor.
-*/
-int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){
+** Determine whether or not a cursor has moved from the position where
+** it was last placed, or has been invalidated for any other reason.
+** Cursors can move when the row they are pointing at is deleted out
+** from under them, for example.  Cursor might also move if a btree
+** is rebalanced.
+**
+** Calling this routine with a NULL cursor pointer returns false.
+**
+** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor
+** back to where it ought to be if this routine returns true.
+*/
+int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
+  return pCur && pCur->eState!=CURSOR_VALID;
+}
+
+/*
+** This routine restores a cursor back to its original position after it
+** has been moved by some outside activity (such as a btree rebalance or
+** a row having been deleted out from under the cursor).  
+**
+** On success, the *pDifferentRow parameter is false if the cursor is left
+** pointing at exactly the same row.  *pDifferntRow is the row the cursor
+** was pointing to has been deleted, forcing the cursor to point to some
+** nearby row.
+**
+** This routine should only be called for a cursor that just returned
+** TRUE from sqlite3BtreeCursorHasMoved().
+*/
+int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){
   int rc;
 
-  if( pCur->eState==CURSOR_VALID ){
-    *pHasMoved = 0;
-    return SQLITE_OK;
-  }
+  assert( pCur!=0 );
+  assert( pCur->eState!=CURSOR_VALID );
   rc = restoreCursorPosition(pCur);
   if( rc ){
-    *pHasMoved = 2;
+    *pDifferentRow = 1;
     return rc;
   }
   if( pCur->eState!=CURSOR_VALID || NEVER(pCur->skipNext!=0) ){
-    *pHasMoved = 2;
+    *pDifferentRow = 1;
   }else{
-    *pHasMoved = 1;
+    *pDifferentRow = 0;
   }
   return SQLITE_OK;
 }
index 7118534f93441d0de12f4d90eea0cb69e3a32114..38abdca1a2ff00a5d4d4c365bf23ca60fa1e29d7 100644 (file)
@@ -169,7 +169,8 @@ int sqlite3BtreeMovetoUnpacked(
   int bias,
   int *pRes
 );
-int sqlite3BtreeCursorHasMoved(BtCursor*, int*);
+int sqlite3BtreeCursorHasMoved(BtCursor*);
+int sqlite3BtreeCursorRestore(BtCursor*, int*);
 int sqlite3BtreeDelete(BtCursor*);
 int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
                                   const void *pData, int nData,
index 58f39a48a8998644a6492528f0f300604d002bb5..2037121ddc32ec6a6a6890709a368a00d7e216e0 100644 (file)
@@ -2713,6 +2713,48 @@ void sqlite3VdbeDelete(Vdbe *p){
   sqlite3DbFree(db, p);
 }
 
+/*
+** The cursor "p" has a pending seek operation that has not yet been
+** carried out.  Seek the cursor now.  If an error occurs, return
+** the appropriate error code.
+*/
+static int SQLITE_NOINLINE handleDeferredMoveto(VdbeCursor *p){
+  int res, rc;
+#ifdef SQLITE_TEST
+  extern int sqlite3_search_count;
+#endif
+  assert( p->deferredMoveto );
+  assert( p->isTable );
+  rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
+  if( rc ) return rc;
+  p->lastRowid = p->movetoTarget;
+  if( res!=0 ) return SQLITE_CORRUPT_BKPT;
+  p->rowidIsValid = 1;
+#ifdef SQLITE_TEST
+  sqlite3_search_count++;
+#endif
+  p->deferredMoveto = 0;
+  p->cacheStatus = CACHE_STALE;
+  return SQLITE_OK;
+}
+
+/*
+** Something has moved cursor "p" out of place.  Maybe the row it was
+** pointed to was deleted out from under it.  Or maybe the btree was
+** rebalanced.  Whatever the cause, try to restore "p" to the place it
+** is suppose to be pointing.  If the row was deleted out from under the
+** cursor, set the cursor to point to a NULL row.
+*/
+static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){
+  int isDifferentRow, rc;
+  assert( p->pCursor!=0 );
+  assert( sqlite3BtreeCursorHasMoved(p->pCursor) );
+  rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow);
+  p->cacheStatus = CACHE_STALE;
+  if( isDifferentRow ) p->nullRow = 1;
+  return rc;
+}
+
 /*
 ** Make sure the cursor p is ready to read or write the row to which it
 ** was last positioned.  Return an error code if an OOM fault or I/O error
@@ -2728,29 +2770,10 @@ void sqlite3VdbeDelete(Vdbe *p){
 */
 int sqlite3VdbeCursorMoveto(VdbeCursor *p){
   if( p->deferredMoveto ){
-    int res, rc;
-#ifdef SQLITE_TEST
-    extern int sqlite3_search_count;
-#endif
-    assert( p->isTable );
-    rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
-    if( rc ) return rc;
-    p->lastRowid = p->movetoTarget;
-    if( res!=0 ) return SQLITE_CORRUPT_BKPT;
-    p->rowidIsValid = 1;
-#ifdef SQLITE_TEST
-    sqlite3_search_count++;
-#endif
-    p->deferredMoveto = 0;
-    p->cacheStatus = CACHE_STALE;
-  }else if( p->pCursor ){
-    int hasMoved;
-    int rc = sqlite3BtreeCursorHasMoved(p->pCursor, &hasMoved);
-    if( rc ) return rc;
-    if( hasMoved ){
-      p->cacheStatus = CACHE_STALE;
-      if( hasMoved==2 ) p->nullRow = 1;
-    }
+    return handleDeferredMoveto(p);
+  }
+  if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
+    return handleMovedCursor(p);
   }
   return SQLITE_OK;
 }