/ Check-in [d0af59fe]
Login

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

Overview
Comment:Speed improvement by avoiding a call to sqliteBtreeLast() when inserting a new row into a table. (CVS 763)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:d0af59fe6b9d5d026786e7cce1c49c208a0335cc
User & Date: drh 2002-10-19 20:16:38
Context
2002-10-20
15:46
Make sure malloc(0) always returns NULL. Fix for ticket #171. (CVS 764) check-in: 4622b7ce user: drh tags: trunk
2002-10-19
20:16
Speed improvement by avoiding a call to sqliteBtreeLast() when inserting a new row into a table. (CVS 763) check-in: d0af59fe user: drh tags: trunk
20:13
Fix the URL for pointing to MinGW on the homepage. (CVS 762) check-in: 16aad98a user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
..
79
80
81
82
83
84
85

86
87
88
89
90

91
92
93
94
95
96
97
....
3556
3557
3558
3559
3560
3561
3562



3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574







3575
3576
3577
3578
3579
3580
3581
....
3623
3624
3625
3626
3627
3628
3629

3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644


3645

3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
....
3662
3663
3664
3665
3666
3667
3668

3669
3670

3671
3672
3673
3674
3675
3676
3677
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.179 2002/09/17 03:20:46 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The makefile scans this source file and creates the following
** array of string constants which are the names of all VDBE opcodes.
................................................................................
** 
** Every cursor that the virtual machine has open is represented by an
** instance of the following structure.
*/
struct Cursor {
  BtCursor *pCursor;    /* The cursor structure of the backend */
  int lastRecno;        /* Last recno from a Next or NextIdx operation */

  Bool recnoIsValid;    /* True if lastRecno is valid */
  Bool keyAsData;       /* The OP_Column command works on key instead of data */
  Bool atFirst;         /* True if pointing to first entry */
  Bool useRandomRowid;  /* Generate new record numbers semi-randomly */
  Bool nullRow;         /* True if pointing to a row with no data */

  Btree *pBt;           /* Separate file holding temporary table */
};
typedef struct Cursor Cursor;

/*
** A sorter builds a list of elements to be sorted.  Each element of
** the list is an instance of the following structure.
................................................................................
    ** first few attempts at chosing a random rowid pick values just a little
    ** larger than the previous rowid.  This has been shown experimentally
    ** to double the speed of the COPY operation.
    */
    int res, rx, cnt, x;
    cnt = 0;
    if( !pC->useRandomRowid ){



      rx = sqliteBtreeLast(pC->pCursor, &res);
      if( res ){
        v = 1;
      }else{
        sqliteBtreeKey(pC->pCursor, 0, sizeof(v), (void*)&v);
        v = keyToInt(v);
        if( v==0x7fffffff ){
          pC->useRandomRowid = 1;
        }else{
          v++;
        }
      }







    }
    if( pC->useRandomRowid ){
      v = db->priorNewRowid;
      cnt = 0;
      do{
        if( v==0 || cnt>2 ){
          v = sqliteRandomInteger();
................................................................................
** be a string.  The stack is popped twice by this instruction.
*/
case OP_PutIntKey:
case OP_PutStrKey: {
  int tos = p->tos;
  int nos = p->tos-1;
  int i = pOp->p1;

  VERIFY( if( nos<0 ) goto not_enough_stack; )
  if( VERIFY( i>=0 && i<p->nCursor && ) p->aCsr[i].pCursor!=0 ){
    char *zKey;
    int nKey, iKey;
    if( pOp->opcode==OP_PutStrKey ){
      if( Stringify(p, nos) ) goto no_mem;
      nKey = aStack[nos].n;
      zKey = zStack[nos];
    }else{
      assert( aStack[nos].flags & STK_Int );
      nKey = sizeof(int);
      iKey = intToKey(aStack[nos].i);
      zKey = (char*)&iKey;
      db->lastRowid = aStack[nos].i;
      if( pOp->p2 ) db->nChange++;


    }

    rc = sqliteBtreeInsert(p->aCsr[i].pCursor, zKey, nKey,
                        zStack[tos], aStack[tos].n);
    p->aCsr[i].recnoIsValid = 0;
  }
  POPSTACK;
  POPSTACK;
  break;
}

/* Opcode: Delete P1 P2 *
................................................................................
** a record from within an Next loop.
**
** The row change counter is incremented if P2==1 and is unmodified
** if P2==0.
*/
case OP_Delete: {
  int i = pOp->p1;

  if( VERIFY( i>=0 && i<p->nCursor && ) p->aCsr[i].pCursor!=0 ){
    rc = sqliteBtreeDelete(p->aCsr[i].pCursor);

  }
  if( pOp->p2 ) db->nChange++;
  break;
}

/* Opcode: KeyAsData P1 P2 *
**







|







 







>





>







 







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







 







>

|













>
>
|
>
|

|







 







>
|
|
>







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
..
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
....
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
....
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
....
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.180 2002/10/19 20:16:38 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The makefile scans this source file and creates the following
** array of string constants which are the names of all VDBE opcodes.
................................................................................
** 
** Every cursor that the virtual machine has open is represented by an
** instance of the following structure.
*/
struct Cursor {
  BtCursor *pCursor;    /* The cursor structure of the backend */
  int lastRecno;        /* Last recno from a Next or NextIdx operation */
  int nextRowid;        /* Next rowid returned by OP_NewRowid */
  Bool recnoIsValid;    /* True if lastRecno is valid */
  Bool keyAsData;       /* The OP_Column command works on key instead of data */
  Bool atFirst;         /* True if pointing to first entry */
  Bool useRandomRowid;  /* Generate new record numbers semi-randomly */
  Bool nullRow;         /* True if pointing to a row with no data */
  Bool nextRowidValid;  /* True if the nextRowid field is valid */
  Btree *pBt;           /* Separate file holding temporary table */
};
typedef struct Cursor Cursor;

/*
** A sorter builds a list of elements to be sorted.  Each element of
** the list is an instance of the following structure.
................................................................................
    ** first few attempts at chosing a random rowid pick values just a little
    ** larger than the previous rowid.  This has been shown experimentally
    ** to double the speed of the COPY operation.
    */
    int res, rx, cnt, x;
    cnt = 0;
    if( !pC->useRandomRowid ){
      if( pC->nextRowidValid ){
        v = pC->nextRowid;
      }else{
        rx = sqliteBtreeLast(pC->pCursor, &res);
        if( res ){
          v = 1;
        }else{
          sqliteBtreeKey(pC->pCursor, 0, sizeof(v), (void*)&v);
          v = keyToInt(v);
          if( v==0x7fffffff ){
            pC->useRandomRowid = 1;
          }else{
            v++;
          }
        }
      }
      if( v<0x7fffffff ){
        pC->nextRowidValid = 1;
        pC->nextRowid = v+1;
      }else{
        pC->nextRowidValid = 0;
      }
    }
    if( pC->useRandomRowid ){
      v = db->priorNewRowid;
      cnt = 0;
      do{
        if( v==0 || cnt>2 ){
          v = sqliteRandomInteger();
................................................................................
** be a string.  The stack is popped twice by this instruction.
*/
case OP_PutIntKey:
case OP_PutStrKey: {
  int tos = p->tos;
  int nos = p->tos-1;
  int i = pOp->p1;
  Cursor *pC;
  VERIFY( if( nos<0 ) goto not_enough_stack; )
  if( VERIFY( i>=0 && i<p->nCursor && ) (pC = &p->aCsr[i])->pCursor!=0 ){
    char *zKey;
    int nKey, iKey;
    if( pOp->opcode==OP_PutStrKey ){
      if( Stringify(p, nos) ) goto no_mem;
      nKey = aStack[nos].n;
      zKey = zStack[nos];
    }else{
      assert( aStack[nos].flags & STK_Int );
      nKey = sizeof(int);
      iKey = intToKey(aStack[nos].i);
      zKey = (char*)&iKey;
      db->lastRowid = aStack[nos].i;
      if( pOp->p2 ) db->nChange++;
      if( pC->nextRowidValid && aStack[nos].i>=pC->nextRowid ){
        pC->nextRowidValid = 0;
      }
    }
    rc = sqliteBtreeInsert(pC->pCursor, zKey, nKey,
                        zStack[tos], aStack[tos].n);
    pC->recnoIsValid = 0;
  }
  POPSTACK;
  POPSTACK;
  break;
}

/* Opcode: Delete P1 P2 *
................................................................................
** a record from within an Next loop.
**
** The row change counter is incremented if P2==1 and is unmodified
** if P2==0.
*/
case OP_Delete: {
  int i = pOp->p1;
  Cursor *pC;
  if( VERIFY( i>=0 && i<p->nCursor && ) (pC = &p->aCsr[i])->pCursor!=0 ){
    rc = sqliteBtreeDelete(pC->pCursor);
    pC->nextRowidValid = 0;
  }
  if( pOp->p2 ) db->nChange++;
  break;
}

/* Opcode: KeyAsData P1 P2 *
**