diff --git a/manifest b/manifest index 1c975027ef..43f7f2b8a2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scomments\sand\sspeed\stweaks\sto\sbtree.c.\s(CVS\s1497) -D 2004-05-30T19:19:05 +C Various\sspeed\senhancements.\s(CVS\s1498) +D 2004-05-30T20:46:09 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -24,8 +24,8 @@ F sqlite.def fc4f5734786fe4743cfe2aa98eb2da4b089edb5f F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2 F src/attach.c c315c58cb16fd6e913b3bfa6412aedecb4567fa5 F src/auth.c 5c2f0bea4729c98c2be3b69d6b466fc51448fe79 -F src/btree.c da44b7801ff3b26eebdf3f71c55f105dc38f9e8a -F src/btree.h b65140b5ae891f30d2a39e64b9f0343225553545 +F src/btree.c 3b7ddd0dd491c265227a045b9575786c7947cf49 +F src/btree.h 512706898e248fc5ec9237b9b535cffb9b53f9cd F src/build.c fd36c4a603e23df35aa7f57772d965e1865e39e0 F src/date.c 0eb922af5c5f5e2455f8dc2f98023ed3e04a857e F src/delete.c 72f8febf6170cda830f509c8f9dffbed3df3596c @@ -60,21 +60,21 @@ F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2 F src/tclsqlite.c b314f12760547e4ef090e055f1298f70627450d3 F src/test1.c 32934478366531503d634968db414df17cb38238 F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872 -F src/test3.c 5e4a6d596f982f6f47a5f9f75ede9b4a3b739968 +F src/test3.c 32d35d15ac821f597a58353bb7b0141085259a24 F src/test4.c 34848a9fd31aa65857b20a8bfc03aff77d8c3426 F src/test5.c 9a1f15133f6955f067c5246e564723b5f23ff221 F src/tokenize.c 50a87c7414de54a008427c9fed22e4e86efb6844 F src/trigger.c 258ed8f9583c6b80e5af401cb9cce345c0c689c3 F src/update.c 259f06e7b22c684b2d3dda54a18185892d6e9573 F src/utf.c f8604999a54483533ac20a63879074f01b0df384 -F src/util.c 4df9d9b0d930d81ec581bcb68748e7c48bdc8c7d +F src/util.c 3b647719c0bece41491300b605cff96a7a26f03a F src/vacuum.c 82ce1fc8ecc2e1aa284c13fe38446709f9936c63 -F src/vdbe.c 61ac9d19277f63e78f09a62d278218fe936574a4 +F src/vdbe.c a2131f7846fd2dbe1573bb37fc6d683c455c0ea4 F src/vdbe.h e73f890e0f2a6c42b183d7d6937947930fe4fdeb F src/vdbeInt.h c2bcd6e5a6e6a3753e4c5a368629c3a625719bfc F src/vdbeapi.c 0c5d64c81871cb4fe5407e639604ee95738b6942 -F src/vdbeaux.c 9a86cafac031ba04588510c1225fde5cacf85a66 -F src/vdbemem.c d5f96663627d54ee8ea47f182c92faa57a015704 +F src/vdbeaux.c ec0cccd9611fa6146a7b70ec23112959e63510ec +F src/vdbemem.c 627d714c347f6af8092cc48ae1c06fd774a1ad9c F src/where.c 444a7c3a8b1eb7bba072e489af628555d21d92a4 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242 F test/attach.test 0dd7cf9bf9bc915bce2da4fb616c4ea9c3da64af @@ -204,7 +204,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P a90264c0a4c73097fe0ae8933dcebb15b8eaa2bb -R a1c712ffe17d6f5e6ad47c4f487c8392 +P c86b7c065a798cd108189b96e87d100115862ff2 +R d1973e68e90aa9267e1c93eed75b57c5 U drh -Z 95139f1873fb80187eef449249c9e629 +Z 7599afd42e52bbb72c5888c64d1ac6d1 diff --git a/manifest.uuid b/manifest.uuid index 7b2dd21582..14b67bbab1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c86b7c065a798cd108189b96e87d100115862ff2 \ No newline at end of file +a0db15bba64af0c529d5be366659bca1165ff21b \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index dcf0eac108..8057be79bd 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 78fc61c597..639e55bcd9 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 0ee59bbcf0..a402b31468 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( nKey0 ) 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( nData0 ) nData = n; memcpy(zStatic, zBuf, (int)nData); diff --git a/src/util.c b/src/util.c index 4aea0c802d..e8b10a05f7 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 @@ -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 5346dec901..5b773fb51d 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 && availkeyAsData, &sMem); if( rc!=SQLITE_OK ){ goto abort_due_to_error; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index cced215375..0f2b317ede 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; nflags = 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; nflags = 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; nflags = 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 69e1c393a2..fbc3ef7b71 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{