/ Check-in [a90264c0]
Login

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

Overview
Comment:Additional minor speed improvements. (CVS 1496)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: a90264c0a4c73097fe0ae8933dcebb15b8eaa2bb
User & Date: drh 2004-05-30 02:14:18
Context
2004-05-30
19:19
Improved comments and speed tweaks to btree.c. (CVS 1497) check-in: c86b7c06 user: drh tags: trunk
02:14
Additional minor speed improvements. (CVS 1496) check-in: a90264c0 user: drh tags: trunk
01:51
Faster version of sqlite3VdbeSerialGet. (CVS 1495) check-in: 80985505 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.149 2004/05/29 21:46:49 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
................................................................................
** Make sure the BtCursor.info field of the given cursor is valid.
** If it is not already valid, call parseCell() to fill it in.
**
** BtCursor.info is a cache of the information in the current cell.
** Using this cache reduces the number of calls to parseCell().
*/
static void getCellInfo(BtCursor *pCur){
  MemPage *pPage = pCur->pPage;
  if( !pCur->infoValid ){
    parseCell(pPage, pCur->idx, &pCur->info);
    pCur->infoValid = 1;
  }else{
#ifndef NDEBUG
    CellInfo info;
    parseCell(pPage, pCur->idx, &info);
    assert( memcmp(&info, &pCur->info, sizeof(info))==0 );
#endif
  }
}

/*
** Set *pSize to the size of the buffer needed to hold the value of







|







 







<

|




|







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
1501
1502
1503
1504
1505
1506
1507

1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.150 2004/05/30 02:14:18 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
................................................................................
** Make sure the BtCursor.info field of the given cursor is valid.
** If it is not already valid, call parseCell() to fill it in.
**
** BtCursor.info is a cache of the information in the current cell.
** Using this cache reduces the number of calls to parseCell().
*/
static void getCellInfo(BtCursor *pCur){

  if( !pCur->infoValid ){
    parseCell(pCur->pPage, pCur->idx, &pCur->info);
    pCur->infoValid = 1;
  }else{
#ifndef NDEBUG
    CellInfo info;
    parseCell(pCur->pPage, pCur->idx, &info);
    assert( memcmp(&info, &pCur->info, sizeof(info))==0 );
#endif
  }
}

/*
** Set *pSize to the size of the buffer needed to hold the value of

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144
...
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
...
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
....
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
....
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
....
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
....
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
....
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
**
** 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.347 2004/05/29 11:24:50 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
/*
** Argument pMem points at a memory cell that will be passed to a
** user-defined function or returned to the user as the result of a query.
** The second argument, 'db_enc' is the text encoding used by the vdbe for
** stack variables.  This routine sets the pMem->enc and pMem->type
** variables used by the sqlite3_value_*() routines.
*/

static void StoreTypeInfo(Mem *pMem, u8 db_enc){
  int flags = pMem->flags;
  if( flags & MEM_Null ){
    pMem->type = SQLITE3_NULL;
  }
  else if( flags & MEM_Int ){
    pMem->type = SQLITE3_INTEGER;
  }
................................................................................
** If P1 is zero and P3 is not zero, then the value is derived from P3.
*/
case OP_Integer: {
  pTos++;
  if( pOp->p3==0 ){
    pTos->flags = MEM_Int;
    pTos->i = pOp->p1;
    pTos->type = SQLITE3_INTEGER;
  }else{
    pTos->flags = MEM_Str|MEM_Static|MEM_Term;
    pTos->z = pOp->p3;
    pTos->n = strlen(pTos->z);
    pTos->enc = TEXT_Utf8;
    Integerify(pTos, 0);
  }
................................................................................
case OP_Callback: {
  int i;
  assert( p->nResColumn==pOp->p1 );

  for(i=0; i<pOp->p1; i++){
    Mem *pVal = &pTos[0-i];
    sqlite3VdbeMemNulTerminate(pVal);
    StoreTypeInfo(pVal, db->enc);
  }

  p->resOnStack = 1;
  p->nCallback++;
  p->popStack = pOp->p1;
  p->pc = pc + 1;
  p->pTos = pTos;
................................................................................
    if( pOp->p2==0 ){
      popStack(&pTos, nField);
    }
    pTos++;
    pTos->n = j;
    pTos->flags = MEM_Str|MEM_Dyn|MEM_Term;
    pTos->enc = db->enc;
    pTos->type = SQLITE3_TEXT;
    pTos->z = zNew;
  }
  break;
}

/* Opcode: Add * * *
**
................................................................................
  n = pOp->p1;
  apVal = p->apArg;
  assert( apVal || n==0 );

  pArg = &pTos[1-n];
  for(i=0; i<n; i++, pArg++){
    apVal[i] = pArg;
    StoreTypeInfo(pArg, db->enc);
  }

  ctx.pFunc = (FuncDef*)pOp->p3;
  ctx.s.flags = MEM_Null;
  ctx.s.z = 0;
  ctx.isError = 0;
  ctx.isStep = 0;
................................................................................
    }
    pTos->i = v;
  }else{
    goto mismatch;
  }
  Release(pTos);
  pTos->flags = MEM_Int;
  pTos->type = SQLITE3_INTEGER;
  break;

mismatch:
  if( pOp->p2==0 ){
    rc = SQLITE_MISMATCH;
    goto abort_due_to_error;
  }else{
................................................................................
  if( pSorter!=0 ){
    p->pSort = pSorter->pNext;
    pTos++;
    pTos->z = pSorter->pData;
    pTos->n = pSorter->nData;
    pTos->flags = MEM_Blob|MEM_Dyn|MEM_Term;
    pTos->enc = 0;
    pTos->type = SQLITE3_BLOB;
    sqliteFree(pSorter->zKey);
    sqliteFree(pSorter);
  }else{
    pc = pOp->p2 - 1;
  }
  break;
}
................................................................................
  assert( pRec>=p->aStack );

  apVal = p->apArg;
  assert( apVal || n==0 );

  for(i=0; i<n; i++, pRec++){
    apVal[i] = pRec;
    StoreTypeInfo(pRec, db->enc);
  }
  i = pTos->i;
  assert( i>=0 && i<p->agg.nMem );
  ctx.pFunc = (FuncDef*)pOp->p3;
  pMem = &p->agg.pCurrent->aMem[i];
  ctx.s.z = pMem->zShort;  /* Space used for small aggregate contexts */
  ctx.pAgg = pMem->z;







|







 







>
|







 







<







 







|







 







<







 







|







 







<







 







<







 







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
...
666
667
668
669
670
671
672

673
674
675
676
677
678
679
...
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
....
1089
1090
1091
1092
1093
1094
1095

1096
1097
1098
1099
1100
1101
1102
....
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
....
1427
1428
1429
1430
1431
1432
1433

1434
1435
1436
1437
1438
1439
1440
....
4092
4093
4094
4095
4096
4097
4098

4099
4100
4101
4102
4103
4104
4105
....
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
**
** 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.348 2004/05/30 02:14:18 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
/*
** Argument pMem points at a memory cell that will be passed to a
** user-defined function or returned to the user as the result of a query.
** The second argument, 'db_enc' is the text encoding used by the vdbe for
** stack variables.  This routine sets the pMem->enc and pMem->type
** variables used by the sqlite3_value_*() routines.
*/
#define storeTypeInfo(A,B) _storeTypeInfo(A)
static void _storeTypeInfo(Mem *pMem){
  int flags = pMem->flags;
  if( flags & MEM_Null ){
    pMem->type = SQLITE3_NULL;
  }
  else if( flags & MEM_Int ){
    pMem->type = SQLITE3_INTEGER;
  }
................................................................................
** If P1 is zero and P3 is not zero, then the value is derived from P3.
*/
case OP_Integer: {
  pTos++;
  if( pOp->p3==0 ){
    pTos->flags = MEM_Int;
    pTos->i = pOp->p1;

  }else{
    pTos->flags = MEM_Str|MEM_Static|MEM_Term;
    pTos->z = pOp->p3;
    pTos->n = strlen(pTos->z);
    pTos->enc = TEXT_Utf8;
    Integerify(pTos, 0);
  }
................................................................................
case OP_Callback: {
  int i;
  assert( p->nResColumn==pOp->p1 );

  for(i=0; i<pOp->p1; i++){
    Mem *pVal = &pTos[0-i];
    sqlite3VdbeMemNulTerminate(pVal);
    storeTypeInfo(pVal, db->enc);
  }

  p->resOnStack = 1;
  p->nCallback++;
  p->popStack = pOp->p1;
  p->pc = pc + 1;
  p->pTos = pTos;
................................................................................
    if( pOp->p2==0 ){
      popStack(&pTos, nField);
    }
    pTos++;
    pTos->n = j;
    pTos->flags = MEM_Str|MEM_Dyn|MEM_Term;
    pTos->enc = db->enc;

    pTos->z = zNew;
  }
  break;
}

/* Opcode: Add * * *
**
................................................................................
  n = pOp->p1;
  apVal = p->apArg;
  assert( apVal || n==0 );

  pArg = &pTos[1-n];
  for(i=0; i<n; i++, pArg++){
    apVal[i] = pArg;
    storeTypeInfo(pArg, db->enc);
  }

  ctx.pFunc = (FuncDef*)pOp->p3;
  ctx.s.flags = MEM_Null;
  ctx.s.z = 0;
  ctx.isError = 0;
  ctx.isStep = 0;
................................................................................
    }
    pTos->i = v;
  }else{
    goto mismatch;
  }
  Release(pTos);
  pTos->flags = MEM_Int;

  break;

mismatch:
  if( pOp->p2==0 ){
    rc = SQLITE_MISMATCH;
    goto abort_due_to_error;
  }else{
................................................................................
  if( pSorter!=0 ){
    p->pSort = pSorter->pNext;
    pTos++;
    pTos->z = pSorter->pData;
    pTos->n = pSorter->nData;
    pTos->flags = MEM_Blob|MEM_Dyn|MEM_Term;
    pTos->enc = 0;

    sqliteFree(pSorter->zKey);
    sqliteFree(pSorter);
  }else{
    pc = pOp->p2 - 1;
  }
  break;
}
................................................................................
  assert( pRec>=p->aStack );

  apVal = p->apArg;
  assert( apVal || n==0 );

  for(i=0; i<n; i++, pRec++){
    apVal[i] = pRec;
    storeTypeInfo(pRec, db->enc);
  }
  i = pTos->i;
  assert( i>=0 && i<p->agg.nMem );
  ctx.pFunc = (FuncDef*)pOp->p3;
  pMem = &p->agg.pCurrent->aMem[i];
  ctx.s.z = pMem->zShort;  /* Space used for small aggregate contexts */
  ctx.pAgg = pMem->z;

Changes to src/vdbeaux.c.

1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
....
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
    }
    for(n=0; n<len; n++){
      v = (v<<8) | buf[n];
    }
    if( serial_type==5 ){
      pMem->flags = MEM_Real;
      pMem->r = *(double*)&v;
      pMem->type = SQLITE3_FLOAT;
    }else{
      pMem->flags = MEM_Int;
      pMem->i = *(i64*)&v;
      pMem->type = SQLITE3_INTEGER;
    }
  }else if( serial_type>=12 ){
    /* String or blob */
    pMem->z = (char *)buf;
    pMem->n = len;
    if( serial_type&0x01 ){
      pMem->flags = MEM_Str | MEM_Ephem;
................................................................................
      pMem->flags = MEM_Blob | MEM_Ephem;
    }
  }else{
    /* NULL */
    assert( serial_type==6 );
    assert( len==0 );
    pMem->flags = MEM_Null;
    pMem->type = SQLITE3_NULL;
  }
  return len;
}

/*
** The following is the comparison function for (non-integer)
** keys in the btrees.  This function returns negative, zero, or







<



<







 







<







1237
1238
1239
1240
1241
1242
1243

1244
1245
1246

1247
1248
1249
1250
1251
1252
1253
....
1255
1256
1257
1258
1259
1260
1261

1262
1263
1264
1265
1266
1267
1268
    }
    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 */
    pMem->z = (char *)buf;
    pMem->n = len;
    if( serial_type&0x01 ){
      pMem->flags = MEM_Str | MEM_Ephem;
................................................................................
      pMem->flags = MEM_Blob | MEM_Ephem;
    }
  }else{
    /* NULL */
    assert( serial_type==6 );
    assert( len==0 );
    pMem->flags = MEM_Null;

  }
  return len;
}

/*
** The following is the comparison function for (non-integer)
** keys in the btrees.  This function returns negative, zero, or