-C Do\snot\sreset\sthe\scursor\sbefore\sseeking\sit\sin\ssqlite3BtreeInsert().\sThis\sspeeds\sup\sINSERT\soperations\sthat\suse\sauto-generated\srowid\svalues.\s(CVS\s6591)
-D 2009-05-02T07:36:50
+C When\sa\scursor\spoints\sat\sthe\slast\sentry\sof\san\sintkey\sbtree\safter\san\sinsert,\sleave\sit\sthere\s(instead\sof\smoving\sit\sto\sthe\stree\sroot\snode).\sThis\sspeeds\sup\sstatements\sof\sthe\sform\s"INSERT\sINTO\s...\sSELECT\s..."\sthat\suse\sauto-generated\srowids.\s(CVS\s6592)
+D 2009-05-02T10:03:09
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/backup.c 0082d0e5a63f04e88faee0dff0a7d63d3e92a78d
F src/bitvec.c ef370407e03440b0852d05024fb016b14a471d3d
F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c
-F src/btree.c 1201cba9e4ccd029a2b88431d14e315c086af6ba
+F src/btree.c 64ad8841aefce2ba0cb3b138e5fe8669ce5fa6db
F src/btree.h 99fcc7e8c4a1e35afe271bcb38de1a698dfc904e
F src/btreeInt.h df64030d632f8c8ac217ed52e8b6b3eacacb33a5
F src/build.c a079f965feea2d0b469b293e09cd0ac41be1272f
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P 7d2b80c7addc2d03d49647da9c6df9113f01349d
-R be37f24bb5752583479cd908d65ba960
+P 20c4acc291def33980f584f882c76e85ee1c8238
+R 473bd4e478192dc26a9afe58e69a17f0
U danielk1977
-Z 771348bde250b0527ce1a0ce0c034f60
+Z 5fda7c8bdbaa8fda519ae98860016fe1
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.604 2009/05/02 07:36:50 danielk1977 Exp $
+** $Id: btree.c,v 1.605 2009/05/02 10:03:09 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
assert( cursorHoldsMutex(pCur) );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
+
+ /* If the cursor already points to the last entry, this is a no-op. */
+ if( CURSOR_VALID==pCur->eState && pCur->atLast ){
+#ifdef SQLITE_DEBUG
+ /* This block serves to assert() that the cursor really does point
+ ** to the last entry in the b-tree. */
+ int ii;
+ for(ii=0; ii<pCur->iPage; ii++){
+ assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
+ }
+ assert( pCur->aiIdx[pCur->iPage]==pCur->apPage[pCur->iPage]->nCell-1 );
+ assert( pCur->apPage[pCur->iPage]->leaf );
+#endif
+ return SQLITE_OK;
+ }
+
rc = moveToRoot(pCur);
if( rc==SQLITE_OK ){
if( CURSOR_INVALID==pCur->eState ){
assert( pPage->leaf );
}
rc = insertCell(pPage, idx, newCell, szNew, 0, 0);
- if( rc==SQLITE_OK ){
+ assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 );
+
+ /* If no error has occured, call balance() to deal with any overflow and
+ ** move the cursor to point at the root of the table (since balance may
+ ** have rearranged the table in such a way as to invalidate BtCursor.apPage[]
+ ** or BtCursor.aiIdx[]).
+ **
+ ** Except, if all of the following are true, do nothing:
+ **
+ ** * Inserting the new cell did not cause overflow,
+ **
+ ** * Before inserting the new cell the cursor was pointing at the
+ ** largest key in an intkey B-Tree, and
+ **
+ ** * The key value associated with the new cell is now the largest
+ ** in the B-Tree.
+ **
+ ** In this case the cursor can be safely left pointing at the (new)
+ ** largest key value in the B-Tree. Doing so speeds up inserting a set
+ ** of entries with increasing integer key values via a single cursor
+ ** (comes up with "INSERT INTO ... SELECT ..." statements), as
+ ** the next insert operation is not required to seek the cursor.
+ */
+ if( rc==SQLITE_OK
+ && (pPage->nOverflow || !pCur->atLast || loc>=0 || !pCur->apPage[0]->intKey)
+ ){
rc = balance(pCur, 1);
+ if( rc==SQLITE_OK ){
+ moveToRoot(pCur);
+ }
}
-
+
/* Must make sure nOverflow is reset to zero even if the balance()
** fails. Internal data structure corruption will result otherwise. */
pCur->apPage[pCur->iPage]->nOverflow = 0;
- if( rc==SQLITE_OK ){
- moveToRoot(pCur);
- }
end_insert:
return rc;
}