/ Check-in [9950c0a7]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:When a cursor points at the last entry of an intkey btree after an insert, leave it there (instead of moving it to the tree root node). This speeds up statements of the form "INSERT INTO ... SELECT ..." that use auto-generated rowids. (CVS 6592)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:9950c0a79c82eb7d8495b0b1a8fe117d566e2387
User & Date: danielk1977 2009-05-02 10:03:09
Context
2009-05-02
12:02
Reduce the size of an integer literal in rowhash.tcl so that the test is able to run with the default TCL installation on Mac OS 10.5. (CVS 6593) check-in: 2229acce user: drh tags: trunk
10:03
When a cursor points at the last entry of an intkey btree after an insert, leave it there (instead of moving it to the tree root node). This speeds up statements of the form "INSERT INTO ... SELECT ..." that use auto-generated rowids. (CVS 6592) check-in: 9950c0a7 user: danielk1977 tags: trunk
07:36
Do not reset the cursor before seeking it in sqlite3BtreeInsert(). This speeds up INSERT operations that use auto-generated rowid values. (CVS 6591) check-in: 20c4acc2 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
3917
3918
3919
3920
3921
3922
3923
















3924
3925
3926
3927
3928
3929
3930
....
6206
6207
6208
6209
6210
6211
6212























6213


6214


6215
6216

6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.604 2009/05/02 07:36:50 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

................................................................................
** or set *pRes to 1 if the table is empty.
*/
int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
  int rc;
 
  assert( cursorHoldsMutex(pCur) );
  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
















  rc = moveToRoot(pCur);
  if( rc==SQLITE_OK ){
    if( CURSOR_INVALID==pCur->eState ){
      assert( pCur->apPage[pCur->iPage]->nCell==0 );
      *pRes = 1;
    }else{
      assert( pCur->eState==CURSOR_VALID );
................................................................................
    idx = ++pCur->aiIdx[pCur->iPage];
    pCur->info.nSize = 0;
    pCur->validNKey = 0;
  }else{
    assert( pPage->leaf );
  }
  rc = insertCell(pPage, idx, newCell, szNew, 0, 0);























  if( rc==SQLITE_OK ){


    rc = balance(pCur, 1);


  }


  /* 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;
}

/*
** Delete the entry that the cursor is pointing to.  The cursor
** is left pointing at a arbitrary location.







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>

>
>
|
|
>




<
<
<







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
....
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264



6265
6266
6267
6268
6269
6270
6271
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $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.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

................................................................................
** or set *pRes to 1 if the table is empty.
*/
int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
  int rc;
 
  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( pCur->apPage[pCur->iPage]->nCell==0 );
      *pRes = 1;
    }else{
      assert( pCur->eState==CURSOR_VALID );
................................................................................
    idx = ++pCur->aiIdx[pCur->iPage];
    pCur->info.nSize = 0;
    pCur->validNKey = 0;
  }else{
    assert( pPage->leaf );
  }
  rc = insertCell(pPage, idx, newCell, szNew, 0, 0);
  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;




end_insert:
  return rc;
}

/*
** Delete the entry that the cursor is pointing to.  The cursor
** is left pointing at a arbitrary location.