diff --git a/manifest b/manifest index 22d417b81c..744628383e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 @@ -106,7 +106,7 @@ F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627 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 @@ -727,7 +727,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 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 diff --git a/manifest.uuid b/manifest.uuid index 81dae04fdc..e59e11086a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -20c4acc291def33980f584f882c76e85ee1c8238 \ No newline at end of file +9950c0a79c82eb7d8495b0b1a8fe117d566e2387 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 7241ac7b58..2692539a50 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** 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. @@ -3921,6 +3921,22 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ 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; iiiPage; 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 ){ @@ -6210,17 +6226,42 @@ int sqlite3BtreeInsert( assert( pPage->leaf ); } rc = insertCell(pPage, idx, newCell, szNew, 0, 0); - if( rc==SQLITE_OK ){ - rc = balance(pCur, 1); - } + 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; }