aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2004-05-30 20:46:09 +0000
committerdrh <drh@noemail.net>2004-05-30 20:46:09 +0000
commite51c44f481f1480c8de0666acc949d48ad657f97 (patch)
treefbbd55893973b732b3d0665770055ec52fd97a9e /src
parent271efa5a28eb10210fc16e98c4dc9365e93ba763 (diff)
downloadsqlite-e51c44f481f1480c8de0666acc949d48ad657f97.tar.gz
sqlite-e51c44f481f1480c8de0666acc949d48ad657f97.zip
Various speed enhancements. (CVS 1498)
FossilOrigin-Name: a0db15bba64af0c529d5be366659bca1165ff21b
Diffstat (limited to 'src')
-rw-r--r--src/btree.c64
-rw-r--r--src/btree.h6
-rw-r--r--src/test3.c15
-rw-r--r--src/util.c45
-rw-r--r--src/vdbe.c17
-rw-r--r--src/vdbeaux.c44
-rw-r--r--src/vdbemem.c9
7 files changed, 113 insertions, 87 deletions
diff --git a/src/btree.c b/src/btree.c
index dcf0eac10..8057be79b 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.151 2004/05/30 19:19:05 drh Exp $
+** $Id: btree.c,v 1.152 2004/05/30 20:46:09 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
@@ -1735,11 +1735,9 @@ int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
** Return a pointer to payload information from the entry that the
** pCur cursor is pointing to. The pointer is to the beginning of
** the key if skipKey==0 and it points to the beginning of data if
-** skipKey==1.
-**
-** At least amt bytes of information must be available on the local
-** page or else this routine returns NULL. If amt<0 then the entire
-** key/data must be available.
+** skipKey==1. The number of bytes of available key/data is written
+** into *pAmt. If *pAmt==0, then the value returned will not be
+** a valid pointer.
**
** This routine is an optimization. It is common for the entire key
** and data to fit on the local page and for there to be no overflow
@@ -1754,7 +1752,7 @@ int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
*/
static const unsigned char *fetchPayload(
BtCursor *pCur, /* Cursor pointing to entry to read from */
- int amt, /* Amount requested */
+ int *pAmt, /* Write the number of available bytes here */
int skipKey /* read beginning at data if this is true */
){
unsigned char *aPayload;
@@ -1780,43 +1778,33 @@ static const unsigned char *fetchPayload(
if( skipKey ){
aPayload += nKey;
nLocal = pCur->info.nLocal - nKey;
- if( amt<0 ) amt = pCur->info.nData;
- assert( amt<=pCur->info.nData );
}else{
nLocal = pCur->info.nLocal;
- if( amt<0 ) amt = nKey;
- assert( amt<=nKey );
- }
- if( amt>nLocal ){
- return 0; /* If any of the data is not local, return nothing */
+ if( nLocal>nKey ){
+ nLocal = nKey;
+ }
}
+ *pAmt = nLocal;
return aPayload;
}
/*
-** Return a pointer to the first amt bytes of the key or data
-** for record that cursor pCur is point to if the entire request
-** exists in contiguous memory on the main tree page. If any
-** any part of the request is on an overflow page, return 0.
-** If pCur is not pointing to a valid entry return 0.
-**
-** If amt<0 then return the entire key or data.
+** For the entry that cursor pCur is point to, return as
+** many bytes of the key or data as are available on the local
+** b-tree page. Write the number of available bytes into *pAmt.
**
** The pointer returned is ephemeral. The key/data may move
** or be destroyed on the next call to any Btree routine.
**
** These routines is used to get quick access to key and data
** in the common case where no overflow pages are used.
-**
-** It is a fatal error to call these routines with amt values that
-** are larger than the key/data size.
*/
-const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int amt){
- return (const void*)fetchPayload(pCur, amt, 0);
+const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){
+ return (const void*)fetchPayload(pCur, pAmt, 0);
}
-const void *sqlite3BtreeDataFetch(BtCursor *pCur, int amt){
- return (const void*)fetchPayload(pCur, amt, 1);
+const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){
+ return (const void*)fetchPayload(pCur, pAmt, 1);
}
@@ -2077,15 +2065,19 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
}else{
c = 0;
}
- }else if( (pCellKey = sqlite3BtreeKeyFetch(pCur, nCellKey))!=0 ){
- c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
}else{
- u8 *pCellKey = sqliteMalloc( nCellKey );
- if( pCellKey==0 ) return SQLITE_NOMEM;
- rc = sqlite3BtreeKey(pCur, 0, nCellKey, pCellKey);
- c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
- sqliteFree(pCellKey);
- if( rc ) return rc;
+ int available;
+ pCellKey = fetchPayload(pCur, &available, 0);
+ if( available>=nCellKey ){
+ c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
+ }else{
+ pCellKey = sqliteMallocRaw( nCellKey );
+ if( pCellKey==0 ) return SQLITE_NOMEM;
+ rc = sqlite3BtreeKey(pCur, 0, nCellKey, pCellKey);
+ c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
+ sqliteFree(pCellKey);
+ if( rc ) return rc;
+ }
}
if( c==0 ){
if( pPage->leafData && !pPage->leaf ){
diff --git a/src/btree.h b/src/btree.h
index 78fc61c59..639e55bcd 100644
--- a/src/btree.h
+++ b/src/btree.h
@@ -13,7 +13,7 @@
** subsystem. See comments in the source code for a detailed description
** of what each interface routine does.
**
-** @(#) $Id: btree.h,v 1.48 2004/05/18 10:06:25 danielk1977 Exp $
+** @(#) $Id: btree.h,v 1.49 2004/05/30 20:46:09 drh Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_
@@ -92,8 +92,8 @@ int sqlite3BtreeFlags(BtCursor*);
int sqlite3BtreePrevious(BtCursor*, int *pRes);
int sqlite3BtreeKeySize(BtCursor*, i64 *pSize);
int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
-const void *sqlite3BtreeKeyFetch(BtCursor*, int amt);
-const void *sqlite3BtreeDataFetch(BtCursor*, int amt);
+const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt);
+const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt);
int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
diff --git a/src/test3.c b/src/test3.c
index 0ee59bbcf..a402b3146 100644
--- a/src/test3.c
+++ b/src/test3.c
@@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
-** $Id: test3.c,v 1.38 2004/05/18 15:57:42 drh Exp $
+** $Id: test3.c,v 1.39 2004/05/30 20:46:09 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
@@ -986,6 +986,7 @@ static int btree_fetch_key(
){
BtCursor *pCur;
int n;
+ int amt;
u64 nKey;
const char *zBuf;
char zStatic[1000];
@@ -998,8 +999,8 @@ static int btree_fetch_key(
if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
if( Tcl_GetInt(interp, argv[2], &n) ) return TCL_ERROR;
sqlite3BtreeKeySize(pCur, &nKey);
- zBuf = sqlite3BtreeKeyFetch(pCur, n);
- if( zBuf ){
+ zBuf = sqlite3BtreeKeyFetch(pCur, &amt);
+ if( zBuf && amt>=n ){
assert( nKey<sizeof(zStatic) );
if( n>0 ) nKey = n;
memcpy(zStatic, zBuf, (int)nKey);
@@ -1023,21 +1024,21 @@ static int btree_fetch_data(
){
BtCursor *pCur;
int n;
+ int amt;
u32 nData;
const char *zBuf;
char zStatic[1000];
if( argc!=3 ){
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " ID AMT
-\"", 0);
+ " ID AMT\"", 0);
return TCL_ERROR;
}
if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
if( Tcl_GetInt(interp, argv[2], &n) ) return TCL_ERROR;
sqlite3BtreeDataSize(pCur, &nData);
- zBuf = sqlite3BtreeDataFetch(pCur, n);
- if( zBuf ){
+ zBuf = sqlite3BtreeDataFetch(pCur, &amt);
+ if( zBuf && amt>=n ){
assert( nData<sizeof(zStatic) );
if( n>0 ) nData = n;
memcpy(zStatic, zBuf, (int)nData);
diff --git a/src/util.c b/src/util.c
index 4aea0c802..e8b10a05f 100644
--- a/src/util.c
+++ b/src/util.c
@@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.94 2004/05/28 16:00:22 drh Exp $
+** $Id: util.c,v 1.95 2004/05/30 20:46:09 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
@@ -1233,26 +1233,22 @@ int sqlite3GetVarint(const unsigned char *p, u64 *v){
u64 x64;
int n;
unsigned char c;
- c = p[0];
- if( (c & 0x80)==0 ){
+ if( ((c = p[0]) & 0x80)==0 ){
*v = c;
return 1;
}
x = c & 0x7f;
- c = p[1];
- if( (c & 0x80)==0 ){
+ if( ((c = p[1]) & 0x80)==0 ){
*v = (x<<7) | c;
return 2;
}
x = (x<<7) | (c&0x7f);
- c = p[2];
- if( (c & 0x80)==0 ){
+ if( ((c = p[2]) & 0x80)==0 ){
*v = (x<<7) | c;
return 3;
}
x = (x<<7) | (c&0x7f);
- c = p[3];
- if( (c & 0x80)==0 ){
+ if( ((c = p[3]) & 0x80)==0 ){
*v = (x<<7) | c;
return 4;
}
@@ -1275,13 +1271,32 @@ int sqlite3GetVarint(const unsigned char *p, u64 *v){
** Return the number of bytes read. The value is stored in *v.
*/
int sqlite3GetVarint32(const unsigned char *p, u32 *v){
- int n = 1;
- unsigned char c = p[0];
- u32 x = c & 0x7f;
- while( (c & 0x80)!=0 && n<9 ){
- c = p[n++];
- x = (x<<7) | (c & 0x7f);
+ u32 x;
+ int n;
+ unsigned char c;
+ if( ((c = p[0]) & 0x80)==0 ){
+ *v = c;
+ return 1;
+ }
+ x = c & 0x7f;
+ if( ((c = p[1]) & 0x80)==0 ){
+ *v = (x<<7) | c;
+ return 2;
}
+ x = (x<<7) | (c&0x7f);
+ if( ((c = p[2]) & 0x80)==0 ){
+ *v = (x<<7) | c;
+ return 3;
+ }
+ x = (x<<7) | (c&0x7f);
+ if( ((c = p[3]) & 0x80)==0 ){
+ *v = (x<<7) | c;
+ return 4;
+ }
+ n = 4;
+ do{
+ x = (x<<7) | ((c = p[n++])&0x7f);
+ }while( (c & 0x80)!=0 && n<9 );
*v = x;
return n;
}
diff --git a/src/vdbe.c b/src/vdbe.c
index 5346dec90..5b773fb51 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -43,7 +43,7 @@
** 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.348 2004/05/30 02:14:18 drh Exp $
+** $Id: vdbe.c,v 1.349 2004/05/30 20:46:09 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -1531,9 +1531,10 @@ case OP_Ge: {
}
affinity = (pOp->p1>>8)&0xFF;
- if( affinity=='\0' ) affinity = 'n';
- applyAffinity(pNos, affinity, db->enc);
- applyAffinity(pTos, affinity, db->enc);
+ if( affinity ){
+ applyAffinity(pNos, affinity, db->enc);
+ applyAffinity(pTos, affinity, db->enc);
+ }
assert( pOp->p3type==P3_COLLSEQ || pOp->p3==0 );
res = sqlite3MemCompare(pNos, pTos, (CollSeq*)pOp->p3);
@@ -1889,6 +1890,7 @@ case OP_Column: {
aType = pC->aType;
aOffset = pC->aOffset;
}else{
+ int avail; /* Number of bytes of available data */
if( pC && pC->aType ){
aType = pC->aType;
}else{
@@ -1903,17 +1905,16 @@ case OP_Column: {
if( zRec ){
zData = zRec;
}else{
- int sz = payloadSize<5 ? payloadSize : 5;
if( pC->keyAsData ){
- zData = (char*)sqlite3BtreeKeyFetch(pCrsr, sz);
+ zData = (char*)sqlite3BtreeKeyFetch(pCrsr, &avail);
}else{
- zData = (char*)sqlite3BtreeDataFetch(pCrsr, sz);
+ zData = (char*)sqlite3BtreeDataFetch(pCrsr, &avail);
}
}
idx = sqlite3GetVarint32(zData, &szHdr);
/* Get the complete header text */
- if( !zRec ){
+ if( !zRec && avail<idx ){
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, szHdr, pC->keyAsData, &sMem);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index cced21537..0f2b317ed 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -1229,21 +1229,37 @@ int sqlite3VdbeSerialGet(
assert( serial_type!=0 );
if( serial_type<=5 ){
/* Integer and Real */
- u64 v = 0;
- int n;
-
- if( buf[0]&0x80 ){
- v = -1;
- }
- for(n=0; n<len; n++){
- v = (v<<8) | buf[n];
- }
- if( serial_type==5 ){
- pMem->flags = MEM_Real;
- pMem->r = *(double*)&v;
- }else{
+ if( serial_type<=3 ){
+ /* 32-bit integer type. This is handled by a special case for
+ ** performance reasons. */
+ int v = buf[0];
+ int n;
+ if( v&0x80 ){
+ v |= -256;
+ }
+ for(n=1; n<len; n++){
+ v = (v<<8) | buf[n];
+ }
pMem->flags = MEM_Int;
- pMem->i = *(i64*)&v;
+ pMem->i = v;
+ return n;
+ }else{
+ u64 v = 0;
+ int n;
+
+ if( buf[0]&0x80 ){
+ v = -1;
+ }
+ for(n=0; n<len; n++){
+ v = (v<<8) | buf[n];
+ }
+ if( serial_type==5 ){
+ pMem->flags = MEM_Real;
+ pMem->r = *(double*)&v;
+ }else{
+ pMem->flags = MEM_Int;
+ pMem->i = *(i64*)&v;
+ }
}
}else if( serial_type>=12 ){
/* String or blob */
diff --git a/src/vdbemem.c b/src/vdbemem.c
index 69e1c393a..fbc3ef7b7 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -464,16 +464,17 @@ int sqlite3VdbeMemFromBtree(
int key, /* If true, retrieve from the btree key, not data. */
Mem *pMem /* OUT: Return data in this Mem structure. */
){
- char *zData;
+ char *zData; /* Data from the btree layer */
+ int available; /* Number of bytes available on the local btree page */
if( key ){
- zData = (char *)sqlite3BtreeKeyFetch(pCur, offset+amt);
+ zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);
}else{
- zData = (char *)sqlite3BtreeDataFetch(pCur, offset+amt);
+ zData = (char *)sqlite3BtreeDataFetch(pCur, &available);
}
pMem->n = amt;
- if( zData ){
+ if( offset+amt<=available ){
pMem->z = &zData[offset];
pMem->flags = MEM_Blob|MEM_Ephem;
}else{