-C Improve\sthe\sspeed\sof\sOP_Column\sthrough\sbetter\scaching.\s(CVS\s1577)
-D 2004-06-12T18:12:16
+C Speed\sup\sin\sthe\shandling\sof\sVDBE\scursors.\s(CVS\s1578)
+D 2004-06-12T20:12:51
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F src/utf.c e16737b3fc4201bf7ce9bd8ced5250596aa31b76
F src/util.c 90375fa253137562d536ccdd40b297f0fd7413fc
F src/vacuum.c b921eb778842592e1fb48a9d4cef7e861103878f
-F src/vdbe.c 9f941bbdf0bcbc18fbdfceecbc2322e82084e094
+F src/vdbe.c c71e47262d3d3539a20a489a03b9cde15ef3acb7
F src/vdbe.h 46f74444a213129bc4b5ce40124dd8ed613b0cde
-F src/vdbeInt.h 1cc767a63eefd1d1114e190336588c6d4f70a6a0
+F src/vdbeInt.h ffc7b8ed911c5bf804796a768fdb6f0568010fa2
F src/vdbeapi.c ee350b552fc4c1c695b760f914f69e9c5556e829
-F src/vdbeaux.c 1d0dbaf73c89bd1cc27abad19ee0aa26ab5d03f4
+F src/vdbeaux.c ff7c66b704dc2c35805657f2cb10ad1b00c8ecd2
F src/vdbemem.c 34f59988831ea032b7f526c2c73175f9f4c0f3ad
F src/where.c dda77afaa593cd54e5955ec433076de18faf62f6
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 99a7bd83ac38e14bb936a834634313cf98279a62
-R 1e1692dcb3026c03937468eb4d723051
+P f687977a28eda5ce0aa1cba2fdfb0152443032bc
+R 088c58f79c616faca7f8012c3563c5db
U drh
-Z 511db11f04adc59072cae9559d18a6b6
+Z 661048d261d615dd2ffa1c2c62f56278
** 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.369 2004/06/12 18:12:16 drh Exp $
+** $Id: vdbe.c,v 1.370 2004/06/12 20:12:51 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
}
/*
-** Make sure there is space in the Vdbe structure to hold at least
-** mxCursor cursors. If there is not currently enough space, then
-** allocate more.
-**
-** If a memory allocation error occurs, return 1. Return 0 if
-** everything works.
-*/
-static int expandCursorArraySize(Vdbe *p, int mxCursor){
- if( mxCursor>=p->nCursor ){
- p->apCsr = sqliteRealloc( p->apCsr, (mxCursor+1)*sizeof(Cursor*) );
- if( p->apCsr==0 ) return 1;
- while( p->nCursor<=mxCursor ){
- Cursor *pC;
- p->apCsr[p->nCursor++] = pC = sqliteMalloc( sizeof(Cursor) );
- if( pC==0 ) return 1;
+** Allocate cursor number iCur. Return a pointer to it. Return NULL
+** if we run out of memory.
+*/
+static Cursor *allocateCursor(Vdbe *p, int iCur){
+ Cursor *pCx;
+ if( iCur>=p->nCursor ){
+ int i;
+ p->apCsr = sqliteRealloc( p->apCsr, (iCur+1)*sizeof(Cursor*) );
+ if( p->apCsr==0 ){
+ p->nCursor = 0;
+ return 0;
}
+ for(i=p->nCursor; i<iCur; i++){
+ p->apCsr[i] = 0;
+ }
+ p->nCursor = iCur+1;
+ }else if( p->apCsr[iCur] ){
+ sqlite3VdbeFreeCursor(p->apCsr[iCur]);
}
- return 0;
+ p->apCsr[iCur] = pCx = sqliteMalloc( sizeof(Cursor) );
+ return pCx;
}
/*
*/
case OP_SetNumColumns: {
assert( (pOp->p1)<p->nCursor );
+ assert( p->apCsr[pOp->p1]!=0 );
p->apCsr[pOp->p1]->nField = pOp->p2;
break;
}
** records on the stack, the next entry down on the stack is an integer
** which is the number of records.
*/
+ assert( p1<0 || p->apCsr[p1]!=0 );
if( p1<0 ){
/* Take the record off of the stack */
Mem *pRec = &pTos[p1];
}
}
assert( i>=0 );
- if( expandCursorArraySize(p, i) ) goto no_mem;
- pCur = p->apCsr[i];
- sqlite3VdbeCleanupCursor(pCur);
+ pCur = allocateCursor(p, i);
+ if( pCur==0 ) goto no_mem;
pCur->nullRow = 1;
if( pX==0 ) break;
/* We always provide a key comparison function. If the table being
int i = pOp->p1;
Cursor *pCx;
assert( i>=0 );
- if( expandCursorArraySize(p, i) ) goto no_mem;
- pCx = p->apCsr[i];
- sqlite3VdbeCleanupCursor(pCx);
- memset(pCx, 0, sizeof(*pCx));
+ pCx = allocateCursor(p, i);
+ if( pCx==0 ) goto no_mem;
pCx->nullRow = 1;
rc = sqlite3BtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt);
int i = pOp->p1;
Cursor *pCx;
assert( i>=0 );
- if( expandCursorArraySize(p, i) ) goto no_mem;
- pCx = p->apCsr[i];
- sqlite3VdbeCleanupCursor(pCx);
- memset(pCx, 0, sizeof(*pCx));
+ pCx = allocateCursor(p, i);
+ if( pCx==0 ) goto no_mem;
pCx->nullRow = 1;
pCx->pseudoTable = 1;
pCx->pIncrKey = &pCx->bogusIncrKey;
case OP_Close: {
int i = pOp->p1;
if( i>=0 && i<p->nCursor ){
- sqlite3VdbeCleanupCursor(p->apCsr[i]);
+ sqlite3VdbeFreeCursor(p->apCsr[i]);
+ p->apCsr[i] = 0;
}
break;
}
assert( pTos>=p->aStack );
assert( i>=0 && i<p->nCursor );
pC = p->apCsr[i];
+ assert( pC!=0 );
if( pC->pCursor!=0 ){
int res, oc;
oc = pOp->opcode;
Cursor *pC;
assert( pTos>=p->aStack );
assert( i>=0 && i<p->nCursor );
+ assert( p->apCsr[i]!=0 );
if( (pC = p->apCsr[i])->pCursor!=0 ){
int res, rx;
assert( pC->intKey==0 );
pTos--;
assert( i>=0 && i<=p->nCursor );
pCx = p->apCsr[i];
+ assert( pCx!=0 );
pCrsr = pCx->pCursor;
if( pCrsr!=0 ){
int res, rc;
BtCursor *pCrsr;
assert( pTos>=p->aStack );
assert( i>=0 && i<p->nCursor );
+ assert( p->apCsr[i]!=0 );
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
int res, rx;
u64 iKey;
i64 v = 0;
Cursor *pC;
assert( i>=0 && i<p->nCursor );
+ assert( p->apCsr[i]!=0 );
if( (pC = p->apCsr[i])->pCursor==0 ){
/* The zero initialization above is all that is needed */
}else{
Cursor *pC;
assert( pNos>=p->aStack );
assert( i>=0 && i<p->nCursor );
+ assert( p->apCsr[i]!=0 );
if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){
char *zKey;
i64 nKey;
Cursor *pC;
assert( i>=0 && i<p->nCursor );
pC = p->apCsr[i];
+ assert( pC!=0 );
if( pC->pCursor!=0 ){
sqlite3VdbeCursorMoveto(pC);
rc = sqlite3BtreeDelete(pC->pCursor);
Cursor *pC;
assert( i>=0 && i<p->nCursor );
pC = p->apCsr[i];
+ assert( pC!=0 );
pC->keyAsData = pOp->p2;
break;
}
pTos++;
assert( i>=0 && i<p->nCursor );
pC = p->apCsr[i];
+ assert( pC!=0 );
if( pC->nullRow ){
pTos->flags = MEM_Null;
}else if( pC->pCursor!=0 ){
assert( i>=0 && i<p->nCursor );
pC = p->apCsr[i];
+ assert( pC!=0 );
sqlite3VdbeCursorMoveto(pC);
pTos++;
if( pC->recnoIsValid ){
BtCursor *pCrsr;
Cursor *pC;
+ assert( i>=0 && i<p->nCursor );
+ assert( p->apCsr[i]!=0 );
assert( p->apCsr[i]->keyAsData );
assert( !p->apCsr[i]->pseudoTable );
- assert( i>=0 && i<p->nCursor );
pTos++;
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
u64 amt;
assert( i>=0 && i<p->nCursor );
pC = p->apCsr[i];
+ assert( pC!=0 );
pC->nullRow = 1;
pC->recnoIsValid = 0;
break;
assert( i>=0 && i<p->nCursor );
pC = p->apCsr[i];
+ assert( pC!=0 );
if( (pCrsr = pC->pCursor)!=0 ){
int res;
rc = sqlite3BtreeLast(pCrsr, &res);
assert( i>=0 && i<p->nCursor );
pC = p->apCsr[i];
+ assert( pC!=0 );
if( (pCrsr = pC->pCursor)!=0 ){
rc = sqlite3BtreeFirst(pCrsr, &res);
pC->atFirst = res==0;
CHECK_FOR_INTERRUPT;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
if( (pCrsr = pC->pCursor)!=0 ){
int res;
if( pC->nullRow ){
BtCursor *pCrsr;
assert( pTos>=p->aStack );
assert( i>=0 && i<p->nCursor );
+ assert( p->apCsr[i]!=0 );
assert( pTos->flags & MEM_Blob );
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
int nKey = pTos->n;
assert( pTos>=p->aStack );
assert( pTos->flags & MEM_Blob );
assert( i>=0 && i<p->nCursor );
+ assert( p->apCsr[i]!=0 );
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
int rx, res;
rx = sqlite3BtreeMoveto(pCrsr, pTos->z, pTos->n, &res);
Cursor *pC;
assert( i>=0 && i<p->nCursor );
+ assert( p->apCsr[i]!=0 );
pTos++;
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
i64 rowid;
Cursor *pC;
assert( i>=0 && i<p->nCursor );
+ assert( p->apCsr[i]!=0 );
assert( pTos>=p->aStack );
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
int res, rc;