-C Improvements\sto\sthe\sdebugging\scode.\s(CVS\s1979)
-D 2004-09-24T19:39:27
+C Optimizations\sto\svdbeaux.c\sand\sprintf.c\s(CVS\s1980)
+D 2004-09-24T22:32:31
F Makefile.in abdeb5bd9d017822691884935c320037c33f6ee6
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13
F src/os_win.c 9e2887825b1a32f0ceb1b73b93ffe29a112cd86f
F src/os_win.h babd4e912967c6b09088cfe38a45e8005a07ba44
-F src/pager.c db8f6cb80798091fcff95c1f86873381fbfefee6
+F src/pager.c 705a61117f05d7dd031762408f9a279834e88c3a
F src/pager.h 67739fe649f33be55dba522ca8a9cc4e42d14f71
F src/parse.y 9389af67bd49b8e5c9d2968b3315a30565b4a200
F src/pragma.c 5fb6647fda4c95edb08447a505e6c98c041e5b31
-F src/printf.c 74ee8eed5983226d1953b46b8ed7d9a55937c145
+F src/printf.c 40770e1f553612d13dfc86d236086e69baa62fe1
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
F src/select.c 13a4e6d0ca2bce8be60e26a499060524fef2e28c
F src/shell.c 0856973c2b94e22664bc43f398ba3fc22d5e080c
F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181
F src/vdbeInt.h 6017100adff362b8dfa37a69e3f1431f084bfa5b
F src/vdbeapi.c f1e060aae5adace5f3a6ae2b0527cfe73e880f1c
-F src/vdbeaux.c 082d63e06c276bd600c7d8ddad361cb9f67590ea
+F src/vdbeaux.c dc3848209aee05b32636a9c1dd913a56ef8dac79
F src/vdbemem.c ef9ac7d32acfe4bce5c5b408b1294c8d9e0cdb56
F src/where.c 5d573333c07f259c8d3b8423d82ba774b78b63a9
F test/all.test 929bfa932b55e75c96fe2203f7650ba451c1862c
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 1ee3a787ada5abd460200d5812474161bfd1cc71
-R 15484f1b24114da1012f0baff327a290
+P bdc3bb070f7f29713b7bb9a6454a7ecbee6cf36d
+R 07e2fbac83a5f125e4876d6fcf9bf7e8
U drh
-Z 4e3ae2dfcca5df52050a8ce4b9bedbca
+Z 242bf20dc4f04b5461b10f0143a31a44
-bdc3bb070f7f29713b7bb9a6454a7ecbee6cf36d
\ No newline at end of file
+eabc77c99b3e78b4c620a1736d9acfa6cb1e7b67
\ No newline at end of file
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.163 2004/09/08 20:13:05 drh Exp $
+** @(#) $Id: pager.c,v 1.164 2004/09/24 22:32:31 drh Exp $
*/
#include "os.h" /* Must be first to enable large file support */
#include "sqliteInt.h"
PgHdr *pFirstSynced; /* First free page with PgHdr.needSync==0 */
PgHdr *pAll; /* List of all pages */
PgHdr *pStmt; /* List of pages in the statement subjournal */
- PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number to PgHdr */
off_t journalOff; /* Current byte offset in the journal file */
off_t journalHdr; /* Byte offset to previous journal header */
off_t stmtHdrOff; /* First journal header written this statement */
off_t stmtCksum; /* cksumInit when statement was started */
int sectorSize; /* Assumed sector size during rollback */
+ PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number to PgHdr */
};
/*
etByte base; /* The base for radix conversion */
etByte flags; /* One or more of FLAG_ constants below */
etByte type; /* Conversion paradigm */
- char *charset; /* The character set for conversion */
- char *prefix; /* Prefix on non-zero values in alt format */
+ etByte charset; /* Offset into aDigits[] of the digits string */
+ etByte prefix; /* Offset into aPrefix[] of the prefix string */
} et_info;
/*
** The following table is searched linearly, so it is good to put the
** most frequently used conversion types first.
*/
+static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
+static const char aPrefix[] = "-x0\000X0";
static et_info fmtinfo[] = {
- { 'd', 10, 1, etRADIX, "0123456789", 0 },
- { 's', 0, 0, etSTRING, 0, 0 },
- { 'z', 0, 2, etDYNSTRING, 0, 0 },
- { 'q', 0, 0, etSQLESCAPE, 0, 0 },
- { 'Q', 0, 0, etSQLESCAPE2, 0, 0 },
- { 'c', 0, 0, etCHARX, 0, 0 },
- { 'o', 8, 0, etRADIX, "01234567", "0" },
- { 'u', 10, 0, etRADIX, "0123456789", 0 },
- { 'x', 16, 0, etRADIX, "0123456789abcdef", "x0" },
- { 'X', 16, 0, etRADIX, "0123456789ABCDEF", "X0" },
- { 'f', 0, 1, etFLOAT, 0, 0 },
- { 'e', 0, 1, etEXP, "e", 0 },
- { 'E', 0, 1, etEXP, "E", 0 },
- { 'g', 0, 1, etGENERIC, "e", 0 },
- { 'G', 0, 1, etGENERIC, "E", 0 },
- { 'i', 10, 1, etRADIX, "0123456789", 0 },
- { 'n', 0, 0, etSIZE, 0, 0 },
- { '%', 0, 0, etPERCENT, 0, 0 },
- { 'p', 16, 0, etPOINTER, "0123456789abcdef", "x0" },
- { 'T', 0, 2, etTOKEN, 0, 0 },
- { 'S', 0, 2, etSRCLIST, 0, 0 },
+ { 'd', 10, 1, etRADIX, 0, 0 },
+ { 's', 0, 0, etSTRING, 0, 0 },
+ { 'z', 0, 2, etDYNSTRING, 0, 0 },
+ { 'q', 0, 0, etSQLESCAPE, 0, 0 },
+ { 'Q', 0, 0, etSQLESCAPE2, 0, 0 },
+ { 'c', 0, 0, etCHARX, 0, 0 },
+ { 'o', 8, 0, etRADIX, 0, 2 },
+ { 'u', 10, 0, etRADIX, 0, 0 },
+ { 'x', 16, 0, etRADIX, 16, 1 },
+ { 'X', 16, 0, etRADIX, 0, 4 },
+ { 'f', 0, 1, etFLOAT, 0, 0 },
+ { 'e', 0, 1, etEXP, 30, 0 },
+ { 'E', 0, 1, etEXP, 14, 0 },
+ { 'g', 0, 1, etGENERIC, 30, 0 },
+ { 'G', 0, 1, etGENERIC, 14, 0 },
+ { 'i', 10, 1, etRADIX, 0, 0 },
+ { 'n', 0, 0, etSIZE, 0, 0 },
+ { '%', 0, 0, etPERCENT, 0, 0 },
+ { 'p', 16, 0, etPOINTER, 0, 1 },
+ { 'T', 0, 2, etTOKEN, 0, 0 },
+ { 'S', 0, 2, etSRCLIST, 0, 0 },
};
#define etNINFO (sizeof(fmtinfo)/sizeof(fmtinfo[0]))
}
bufpt = &buf[etBUFSIZE-1];
{
- register char *cset; /* Use registers for speed */
+ register const char *cset; /* Use registers for speed */
register int base;
- cset = infop->charset;
+ cset = &aDigits[infop->charset];
base = infop->base;
do{ /* Convert to ascii */
*(--bufpt) = cset[longvalue%base];
}
if( prefix ) *(--bufpt) = prefix; /* Add sign */
if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
- char *pre, x;
- pre = infop->prefix;
+ const char *pre;
+ char x;
+ pre = &aPrefix[infop->prefix];
if( *bufpt!=pre[0] ){
- for(pre=infop->prefix; (x=(*pre))!=0; pre++) *(--bufpt) = x;
+ for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
}
}
length = &buf[etBUFSIZE-1]-bufpt;
}
bufpt++; /* point to next free slot */
if( exp || flag_exp ){
- *(bufpt++) = infop->charset[0];
+ *(bufpt++) = aDigits[infop->charset];
if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; } /* sign of exp */
else { *(bufpt++) = '+'; }
if( exp>=100 ){
** and segfaults if you give it a long long int.
*/
void sqlite3DebugPrintf(const char *zFormat, ...){
+ extern int getpid(void);
va_list ap;
char zBuf[500];
va_start(ap, zFormat);
p->trace = trace;
}
+/*
+** Resize the Vdbe.aOp array so that it contains at least N
+** elements.
+*/
+static void resizeOpArray(Vdbe *p, int N){
+ if( p->nOpAlloc<N ){
+ int oldSize = p->nOpAlloc;
+ p->nOpAlloc = N+100;
+ p->aOp = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
+ if( p->aOp ){
+ memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
+ }
+ }
+}
+
/*
** Add a new instruction to the list of instructions current in the
** VDBE. Return the address of the new instruction.
i = p->nOp;
p->nOp++;
assert( p->magic==VDBE_MAGIC_INIT );
- if( i>=p->nOpAlloc ){
- int oldSize = p->nOpAlloc;
- Op *aNew;
- p->nOpAlloc = p->nOpAlloc*2 + 100;
- aNew = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
- if( aNew==0 ){
- p->nOpAlloc = oldSize;
- return 0;
- }
- p->aOp = aNew;
- memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
+ resizeOpArray(p, i+1);
+ if( p->aOp==0 ){
+ return 0;
}
pOp = &p->aOp[i];
pOp->opcode = op;
pOp->p1 = p1;
- if( p2<0 && (-1-p2)<p->nLabel && p->aLabel[-1-p2]>=0 ){
- p2 = p->aLabel[-1-p2];
- }
pOp->p2 = p2;
pOp->p3 = 0;
pOp->p3type = P3_NOTUSED;
i = p->nLabel++;
assert( p->magic==VDBE_MAGIC_INIT );
if( i>=p->nLabelAlloc ){
- int *aNew;
p->nLabelAlloc = p->nLabelAlloc*2 + 10;
- aNew = sqliteRealloc( p->aLabel, p->nLabelAlloc*sizeof(p->aLabel[0]));
- if( aNew==0 ){
- sqliteFree(p->aLabel);
- }
- p->aLabel = aNew;
+ p->aLabel = sqliteRealloc( p->aLabel, p->nLabelAlloc*sizeof(p->aLabel[0]));
}
- if( p->aLabel==0 ){
- p->nLabel = 0;
- p->nLabelAlloc = 0;
- return 0;
+ if( p->aLabel ){
+ p->aLabel[i] = -1;
}
- p->aLabel[i] = -1;
return -1-i;
}
** a prior call to sqlite3VdbeMakeLabel().
*/
void sqlite3VdbeResolveLabel(Vdbe *p, int x){
- int j;
+ int j = -1-x;
assert( p->magic==VDBE_MAGIC_INIT );
- if( x<0 && (-x)<=p->nLabel && p->aOp ){
- if( p->aLabel[-1-x]==p->nOp ) return;
- assert( p->aLabel[-1-x]<0 );
- p->aLabel[-1-x] = p->nOp;
- for(j=0; j<p->nOp; j++){
- if( p->aOp[j].p2==x ) p->aOp[j].p2 = p->nOp;
- }
+ assert( j>=0 && j<p->nLabel );
+ if( p->aLabel ){
+ p->aLabel[j] = p->nOp;
}
}
+/*
+** Loop through the program looking for P2 values that are negative.
+** Each such value is a label. Resolve the label by setting the P2
+** value to its correct non-zero value.
+**
+** This routine is called once after all opcodes have been inserted.
+*/
+static void resolveP2Values(Vdbe *p){
+ int i;
+ Op *pOp;
+ int *aLabel = p->aLabel;
+ if( aLabel==0 ) return;
+ for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
+ if( pOp->p2>=0 ) continue;
+ assert( -1-pOp->p2<p->nLabel );
+ pOp->p2 = aLabel[-1-pOp->p2];
+ }
+ sqliteFree(p->aLabel);
+ p->aLabel = 0;
+}
+
/*
** Return the address of the next instruction to be inserted.
*/
int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
int addr;
assert( p->magic==VDBE_MAGIC_INIT );
- if( p->nOp + nOp >= p->nOpAlloc ){
- int oldSize = p->nOpAlloc;
- Op *aNew;
- p->nOpAlloc = p->nOpAlloc*2 + nOp + 10;
- aNew = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
- if( aNew==0 ){
- p->nOpAlloc = oldSize;
- return 0;
- }
- p->aOp = aNew;
- memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
+ resizeOpArray(p, p->nOp + nOp);
+ if( p->aOp==0 ){
+ return 0;
}
addr = p->nOp;
if( nOp>0 ){
void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
va_list ap;
assert( p->nOp>0 );
- assert( p->aOp[p->nOp-1].p3==0 );
+ assert( p->aOp==0 || p->aOp[p->nOp-1].p3==0 );
va_start(ap, zFormat);
sqlite3VdbeChangeP3(p, -1, sqlite3VMPrintf(zFormat, ap), P3_DYNAMIC);
va_end(ap);
}
#endif
+/*
+** Release an array of N Mem elements
+*/
+static void releaseMemArray(Mem *p, int N){
+ if( p ){
+ while( N-->0 ){
+ sqlite3VdbeMemRelease(p++);
+ }
+ }
+}
+
/*
** Give a listing of the program in the virtual machine.
**
** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
*/
if( p->pTos==&p->aStack[4] ){
- for(i=0; i<5; i++){
- sqlite3VdbeMemRelease(&p->aStack[i]);
- p->aStack[i].flags = 0;
- }
+ releaseMemArray(p->aStack, 5);
}
p->resOnStack = 0;
** Allocation all the stack space we will ever need.
*/
if( p->aStack==0 ){
+ resolveP2Values(p);
assert( nVar>=0 );
n = isExplain ? 10 : p->nOp;
p->aStack = sqliteMalloc(
static void Cleanup(Vdbe *p){
int i;
if( p->aStack ){
- Mem *pTos = p->pTos;
- while( pTos>=p->aStack ){
- sqlite3VdbeMemRelease(pTos);
- pTos--;
- }
- p->pTos = pTos;
+ releaseMemArray(p->aStack, 1 + (p->pTos - p->aStack));
+ p->pTos = &p->aStack[-1];
}
closeAllCursors(p);
- for(i=0; i<p->nMem; i++){
- sqlite3VdbeMemRelease(&p->aMem[i]);
- }
+ releaseMemArray(p->aMem, p->nMem);
if( p->pList ){
sqlite3VdbeKeylistFree(p->pList);
p->pList = 0;
}
- for(i=0; i<p->contextStackTop; i++){
- sqlite3VdbeKeylistFree(p->contextStack[i].pList);
+ if( p->contextStack ){
+ for(i=0; i<p->contextStackTop; i++){
+ sqlite3VdbeKeylistFree(p->contextStack[i].pList);
+ }
+ sqliteFree(p->contextStack);
}
sqlite3VdbeSorterReset(p);
sqlite3VdbeAggReset(0, &p->agg, 0);
- sqliteFree(p->contextStack);
p->contextStack = 0;
p->contextStackDepth = 0;
p->contextStackTop = 0;
** be called on an SQL statement before sqlite3_step().
*/
void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
+ Mem *pColName;
+ int n;
assert( 0==p->nResColumn );
p->nResColumn = nResColumn;
+ n = nResColumn*2;
+ p->aColName = pColName = (Mem*)sqliteMalloc( sizeof(Mem)*n );
+ if( p->aColName==0 ) return;
+ while( n-- > 0 ){
+ (pColName++)->flags = MEM_Null;
+ }
}
/*
int rc;
Mem *pColName;
assert( idx<(2*p->nResColumn) );
-
- /* If the Vdbe.aColName array has not yet been allocated, allocate
- ** it now.
- */
- if( !p->aColName ){
- int i;
- p->aColName = (Mem *)sqliteMalloc(sizeof(Mem)*p->nResColumn*2);
- if( !p->aColName ){
- return SQLITE_NOMEM;
- }
- for(i=0; i<(2*p->nResColumn); i++){
- p->aColName[i].flags = MEM_Null;
- }
- }
-
+ if( sqlite3_malloc_failed ) return SQLITE_NOMEM;
+ assert( p->aColName!=0 );
pColName = &(p->aColName[idx]);
if( N==P3_DYNAMIC || N==P3_STATIC ){
rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
if( p->pNext ){
p->pNext->pPrev = p->pPrev;
}
- p->pPrev = p->pNext = 0;
- if( p->nOpAlloc==0 ){
- p->aOp = 0;
- p->nOp = 0;
- }
- for(i=0; i<p->nOp; i++){
- Op *pOp = &p->aOp[i];
- if( pOp->p3type==P3_DYNAMIC || pOp->p3type==P3_KEYINFO ){
- sqliteFree(pOp->p3);
- }
- if( pOp->p3type==P3_VDBEFUNC ){
- VdbeFunc *pVdbeFunc = (VdbeFunc *)pOp->p3;
- sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
- sqliteFree(pVdbeFunc);
+ if( p->aOp ){
+ for(i=0; i<p->nOp; i++){
+ Op *pOp = &p->aOp[i];
+ if( pOp->p3type==P3_DYNAMIC || pOp->p3type==P3_KEYINFO ){
+ sqliteFree(pOp->p3);
+ }
+ if( pOp->p3type==P3_VDBEFUNC ){
+ VdbeFunc *pVdbeFunc = (VdbeFunc *)pOp->p3;
+ sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
+ sqliteFree(pVdbeFunc);
+ }
}
+ sqliteFree(p->aOp);
}
- for(i=0; i<p->nVar; i++){
- sqlite3VdbeMemRelease(&p->aVar[i]);
- }
- sqliteFree(p->aOp);
+ releaseMemArray(p->aVar, p->nVar);
sqliteFree(p->aLabel);
sqliteFree(p->aStack);
- if( p->aColName ){
- for(i=0; i<(p->nResColumn)*2; i++){
- sqlite3VdbeMemRelease(&(p->aColName[i]));
- }
- sqliteFree(p->aColName);
- }
+ releaseMemArray(p->aColName, p->nResColumn*2);
+ sqliteFree(p->aColName);
p->magic = VDBE_MAGIC_DEAD;
sqliteFree(p);
}