-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
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
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
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
-3eb084390382c108e9b0ff0b29dede58ebb149bc
\ No newline at end of file
+ce123b5c592556a8cd38b01fcc91ba76231d3098
\ No newline at end of file
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;
}
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,
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
*/
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;
}