| Index: third_party/sqlite/src/test/speedtest1.c
 | 
| diff --git a/third_party/sqlite/src/test/speedtest1.c b/third_party/sqlite/src/test/speedtest1.c
 | 
| index b41c732053c15e1a978a8151bac49bfabc92aaeb..f5b79915c87ccb2007be1aea7012321bbcaa590f 100644
 | 
| --- a/third_party/sqlite/src/test/speedtest1.c
 | 
| +++ b/third_party/sqlite/src/test/speedtest1.c
 | 
| @@ -15,6 +15,7 @@ static const char zHelp[] =
 | 
|    "  --journal M         Set the journal_mode to M\n"
 | 
|    "  --key KEY           Set the encryption key to KEY\n"
 | 
|    "  --lookaside N SZ    Configure lookaside for N slots of SZ bytes each\n"
 | 
| +  "  --mmap SZ           MMAP the first SZ bytes of the database file\n"
 | 
|    "  --multithread       Set multithreaded mode\n"
 | 
|    "  --nomemstat         Disable memory statistics\n"
 | 
|    "  --nosync            Set PRAGMA synchronous=OFF\n"
 | 
| @@ -22,6 +23,7 @@ static const char zHelp[] =
 | 
|    "  --pagesize N        Set the page size to N\n"
 | 
|    "  --pcache N SZ       Configure N pages of pagecache each of size SZ bytes\n"
 | 
|    "  --primarykey        Use PRIMARY KEY instead of UNIQUE where appropriate\n"
 | 
| +  "  --repeat N          Repeat each SELECT N times (default: 1)\n"
 | 
|    "  --reprepare         Reprepare each statement upon every invocation\n"
 | 
|    "  --scratch N SZ      Configure scratch memory for N slots of SZ bytes each\n"
 | 
|    "  --serialized        Set serialized threading mode\n"
 | 
| @@ -30,6 +32,7 @@ static const char zHelp[] =
 | 
|    "  --shrink-memory     Invoke sqlite3_db_release_memory() frequently.\n"
 | 
|    "  --size N            Relative test size.  Default=100\n"
 | 
|    "  --stats             Show statistics at the end\n"
 | 
| +  "  --temp N            N from 0 to 9.  0: no temp table. 9: all temp tables\n"
 | 
|    "  --testset T         Run test-set T\n"
 | 
|    "  --trace             Turn on SQL tracing\n"
 | 
|    "  --threads N         Use up to N threads for sorting\n"
 | 
| @@ -47,15 +50,17 @@ static const char zHelp[] =
 | 
|  #include <stdarg.h>
 | 
|  #include <string.h>
 | 
|  #include <ctype.h>
 | 
| +#ifndef _WIN32
 | 
| +# include <unistd.h>
 | 
| +#else
 | 
| +# include <io.h>
 | 
| +#endif
 | 
|  #define ISSPACE(X) isspace((unsigned char)(X))
 | 
|  #define ISDIGIT(X) isdigit((unsigned char)(X))
 | 
|  
 | 
|  #if SQLITE_VERSION_NUMBER<3005000
 | 
|  # define sqlite3_int64 sqlite_int64
 | 
|  #endif
 | 
| -#ifdef SQLITE_ENABLE_RBU
 | 
| -# include "sqlite3rbu.h"
 | 
| -#endif
 | 
|  
 | 
|  /* All global state is held in this structure */
 | 
|  static struct Global {
 | 
| @@ -69,7 +74,9 @@ static struct Global {
 | 
|    int bExplain;              /* Print SQL with EXPLAIN prefix */
 | 
|    int bVerify;               /* Try to verify that results are correct */
 | 
|    int bMemShrink;            /* Call sqlite3_db_release_memory() often */
 | 
| +  int eTemp;                 /* 0: no TEMP.  9: always TEMP. */
 | 
|    int szTest;                /* Scale factor for test iterations */
 | 
| +  int nRepeat;               /* Repeat selects this many times */
 | 
|    const char *zWR;           /* Might be WITHOUT ROWID */
 | 
|    const char *zNN;           /* Might be NOT NULL */
 | 
|    const char *zPK;           /* Might be UNIQUE or PRIMARY KEY */
 | 
| @@ -78,6 +85,12 @@ static struct Global {
 | 
|    char zResult[3000];        /* Text of the current result */
 | 
|  } g;
 | 
|  
 | 
| +/* Return " TEMP" or "", as appropriate for creating a table.
 | 
| +*/
 | 
| +static const char *isTemp(int N){
 | 
| +  return g.eTemp>=N ? " TEMP" : "";
 | 
| +}
 | 
| +
 | 
|  
 | 
|  /* Print an error message and exit */
 | 
|  static void fatal_error(const char *zMsg, ...){
 | 
| @@ -413,12 +426,14 @@ void speedtest1_run(void){
 | 
|    speedtest1_shrink_memory();
 | 
|  }
 | 
|  
 | 
| +#ifndef SQLITE_OMIT_DEPRECATED
 | 
|  /* The sqlite3_trace() callback function */
 | 
|  static void traceCallback(void *NotUsed, const char *zSql){
 | 
|    int n = (int)strlen(zSql);
 | 
|    while( n>0 && (zSql[n-1]==';' || ISSPACE(zSql[n-1])) ) n--;
 | 
|    fprintf(stderr,"%.*s;\n", n, zSql);
 | 
|  }
 | 
| +#endif /* SQLITE_OMIT_DEPRECATED */
 | 
|  
 | 
|  /* Substitute random() function that gives the same random
 | 
|  ** sequence on each run, for repeatability. */
 | 
| @@ -443,6 +458,68 @@ static int est_square_root(int x){
 | 
|    return y0;
 | 
|  }
 | 
|  
 | 
| +
 | 
| +#if SQLITE_VERSION_NUMBER<3005004
 | 
| +/*
 | 
| +** An implementation of group_concat().  Used only when testing older
 | 
| +** versions of SQLite that lack the built-in group_concat().
 | 
| +*/
 | 
| +struct groupConcat {
 | 
| +  char *z;
 | 
| +  int nAlloc;
 | 
| +  int nUsed;
 | 
| +};
 | 
| +static void groupAppend(struct groupConcat *p, const char *z, int n){
 | 
| +  if( p->nUsed+n >= p->nAlloc ){
 | 
| +    int n2 = (p->nAlloc+n+1)*2;
 | 
| +    char *z2 = sqlite3_realloc(p->z, n2);
 | 
| +    if( z2==0 ) return;
 | 
| +    p->z = z2;
 | 
| +    p->nAlloc = n2;
 | 
| +  }
 | 
| +  memcpy(p->z+p->nUsed, z, n);
 | 
| +  p->nUsed += n;
 | 
| +}
 | 
| +static void groupStep(
 | 
| +  sqlite3_context *context,
 | 
| +  int argc,
 | 
| +  sqlite3_value **argv
 | 
| +){
 | 
| +  const char *zVal;
 | 
| +  struct groupConcat *p;
 | 
| +  const char *zSep;
 | 
| +  int nVal, nSep;
 | 
| +  assert( argc==1 || argc==2 );
 | 
| +  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
 | 
| +  p= (struct groupConcat*)sqlite3_aggregate_context(context, sizeof(*p));
 | 
| +
 | 
| +  if( p ){
 | 
| +    int firstTerm = p->nUsed==0;
 | 
| +    if( !firstTerm ){
 | 
| +      if( argc==2 ){
 | 
| +        zSep = (char*)sqlite3_value_text(argv[1]);
 | 
| +        nSep = sqlite3_value_bytes(argv[1]);
 | 
| +      }else{
 | 
| +        zSep = ",";
 | 
| +        nSep = 1;
 | 
| +      }
 | 
| +      if( nSep ) groupAppend(p, zSep, nSep);
 | 
| +    }
 | 
| +    zVal = (char*)sqlite3_value_text(argv[0]);
 | 
| +    nVal = sqlite3_value_bytes(argv[0]);
 | 
| +    if( zVal ) groupAppend(p, zVal, nVal);
 | 
| +  }
 | 
| +}
 | 
| +static void groupFinal(sqlite3_context *context){
 | 
| +  struct groupConcat *p;
 | 
| +  p = sqlite3_aggregate_context(context, 0);
 | 
| +  if( p && p->z ){
 | 
| +    p->z[p->nUsed] = 0;
 | 
| +    sqlite3_result_text(context, p->z, p->nUsed, sqlite3_free);
 | 
| +  }
 | 
| +}
 | 
| +#endif
 | 
| +
 | 
|  /*
 | 
|  ** The main and default testset
 | 
|  */
 | 
| @@ -451,16 +528,17 @@ void testset_main(void){
 | 
|    int n;                        /* iteration count */
 | 
|    int sz;                       /* Size of the tables */
 | 
|    int maxb;                     /* Maximum swizzled value */
 | 
| -  unsigned x1, x2;              /* Parameters */
 | 
| -  int len;                      /* Length of the zNum[] string */
 | 
| +  unsigned x1 = 0, x2 = 0;      /* Parameters */
 | 
| +  int len = 0;                  /* Length of the zNum[] string */
 | 
|    char zNum[2000];              /* A number name */
 | 
|  
 | 
|    sz = n = g.szTest*500;
 | 
| +  zNum[0] = 0;
 | 
|    maxb = roundup_allones(sz);
 | 
|    speedtest1_begin_test(100, "%d INSERTs into table with no index", n);
 | 
|    speedtest1_exec("BEGIN");
 | 
| -  speedtest1_exec("CREATE TABLE t1(a INTEGER %s, b INTEGER %s, c TEXT %s);",
 | 
| -                  g.zNN, g.zNN, g.zNN);
 | 
| +  speedtest1_exec("CREATE%s TABLE t1(a INTEGER %s, b INTEGER %s, c TEXT %s);",
 | 
| +                  isTemp(9), g.zNN, g.zNN, g.zNN);
 | 
|    speedtest1_prepare("INSERT INTO t1 VALUES(?1,?2,?3); --  %d times", n);
 | 
|    for(i=1; i<=n; i++){
 | 
|      x1 = swizzle(i,maxb);
 | 
| @@ -477,8 +555,9 @@ void testset_main(void){
 | 
|    n = sz;
 | 
|    speedtest1_begin_test(110, "%d ordered INSERTS with one index/PK", n);
 | 
|    speedtest1_exec("BEGIN");
 | 
| -  speedtest1_exec("CREATE TABLE t2(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
 | 
| -                   g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
 | 
| +  speedtest1_exec(
 | 
| +     "CREATE%s TABLE t2(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
 | 
| +     isTemp(5), g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
 | 
|    speedtest1_prepare("INSERT INTO t2 VALUES(?1,?2,?3); -- %d times", n);
 | 
|    for(i=1; i<=n; i++){
 | 
|      x1 = swizzle(i,maxb);
 | 
| @@ -495,8 +574,9 @@ void testset_main(void){
 | 
|    n = sz;
 | 
|    speedtest1_begin_test(120, "%d unordered INSERTS with one index/PK", n);
 | 
|    speedtest1_exec("BEGIN");
 | 
| -  speedtest1_exec("CREATE TABLE t3(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
 | 
| -                   g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
 | 
| +  speedtest1_exec(
 | 
| +      "CREATE%s TABLE t3(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
 | 
| +      isTemp(3), g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
 | 
|    speedtest1_prepare("INSERT INTO t3 VALUES(?1,?2,?3); -- %d times", n);
 | 
|    for(i=1; i<=n; i++){
 | 
|      x1 = swizzle(i,maxb);
 | 
| @@ -509,17 +589,23 @@ void testset_main(void){
 | 
|    speedtest1_exec("COMMIT");
 | 
|    speedtest1_end_test();
 | 
|  
 | 
| +#if SQLITE_VERSION_NUMBER<3005004
 | 
| +  sqlite3_create_function(g.db, "group_concat", 1, SQLITE_UTF8, 0,
 | 
| +                          0, groupStep, groupFinal);
 | 
| +#endif
 | 
|  
 | 
|    n = 25;
 | 
|    speedtest1_begin_test(130, "%d SELECTS, numeric BETWEEN, unindexed", n);
 | 
|    speedtest1_exec("BEGIN");
 | 
|    speedtest1_prepare(
 | 
| -    "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
 | 
| +    "SELECT count(*), avg(b), sum(length(c)), group_concat(c) FROM t1\n"
 | 
|      " WHERE b BETWEEN ?1 AND ?2; -- %d times", n
 | 
|    );
 | 
|    for(i=1; i<=n; i++){
 | 
| -    x1 = speedtest1_random()%maxb;
 | 
| -    x2 = speedtest1_random()%10 + sz/5000 + x1;
 | 
| +    if( (i-1)%g.nRepeat==0 ){
 | 
| +      x1 = speedtest1_random()%maxb;
 | 
| +      x2 = speedtest1_random()%10 + sz/5000 + x1;
 | 
| +    }
 | 
|      sqlite3_bind_int(g.pStmt, 1, x1);
 | 
|      sqlite3_bind_int(g.pStmt, 2, x2);
 | 
|      speedtest1_run();
 | 
| @@ -532,16 +618,18 @@ void testset_main(void){
 | 
|    speedtest1_begin_test(140, "%d SELECTS, LIKE, unindexed", n);
 | 
|    speedtest1_exec("BEGIN");
 | 
|    speedtest1_prepare(
 | 
| -    "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
 | 
| +    "SELECT count(*), avg(b), sum(length(c)), group_concat(c) FROM t1\n"
 | 
|      " WHERE c LIKE ?1; -- %d times", n
 | 
|    );
 | 
|    for(i=1; i<=n; i++){
 | 
| -    x1 = speedtest1_random()%maxb;
 | 
| -    zNum[0] = '%';
 | 
| -    len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
 | 
| -    zNum[len] = '%';
 | 
| -    zNum[len+1] = 0;
 | 
| -    sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
 | 
| +    if( (i-1)%g.nRepeat==0 ){
 | 
| +      x1 = speedtest1_random()%maxb;
 | 
| +      zNum[0] = '%';
 | 
| +      len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
 | 
| +      zNum[len] = '%';
 | 
| +      zNum[len+1] = 0;
 | 
| +    }
 | 
| +    sqlite3_bind_text(g.pStmt, 1, zNum, len+1, SQLITE_STATIC);
 | 
|      speedtest1_run();
 | 
|    }
 | 
|    speedtest1_exec("COMMIT");
 | 
| @@ -556,12 +644,14 @@ void testset_main(void){
 | 
|      " ORDER BY a; -- %d times", n
 | 
|    );
 | 
|    for(i=1; i<=n; i++){
 | 
| -    x1 = speedtest1_random()%maxb;
 | 
| -    zNum[0] = '%';
 | 
| -    len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
 | 
| -    zNum[len] = '%';
 | 
| -    zNum[len+1] = 0;
 | 
| -    sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
 | 
| +    if( (i-1)%g.nRepeat==0 ){
 | 
| +      x1 = speedtest1_random()%maxb;
 | 
| +      zNum[0] = '%';
 | 
| +      len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
 | 
| +      zNum[len] = '%';
 | 
| +      zNum[len+1] = 0;
 | 
| +    }
 | 
| +    sqlite3_bind_text(g.pStmt, 1, zNum, len+1, SQLITE_STATIC);
 | 
|      speedtest1_run();
 | 
|    }
 | 
|    speedtest1_exec("COMMIT");
 | 
| @@ -575,12 +665,14 @@ void testset_main(void){
 | 
|      " ORDER BY a LIMIT 10; -- %d times", n
 | 
|    );
 | 
|    for(i=1; i<=n; i++){
 | 
| -    x1 = speedtest1_random()%maxb;
 | 
| -    zNum[0] = '%';
 | 
| -    len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
 | 
| -    zNum[len] = '%';
 | 
| -    zNum[len+1] = 0;
 | 
| -    sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
 | 
| +    if( (i-1)%g.nRepeat==0 ){
 | 
| +      x1 = speedtest1_random()%maxb;
 | 
| +      zNum[0] = '%';
 | 
| +      len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
 | 
| +      zNum[len] = '%';
 | 
| +      zNum[len+1] = 0;
 | 
| +    }
 | 
| +    sqlite3_bind_text(g.pStmt, 1, zNum, len+1, SQLITE_STATIC);
 | 
|      speedtest1_run();
 | 
|    }
 | 
|    speedtest1_exec("COMMIT");
 | 
| @@ -602,12 +694,14 @@ void testset_main(void){
 | 
|    speedtest1_begin_test(160, "%d SELECTS, numeric BETWEEN, indexed", n);
 | 
|    speedtest1_exec("BEGIN");
 | 
|    speedtest1_prepare(
 | 
| -    "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
 | 
| +    "SELECT count(*), avg(b), sum(length(c)), group_concat(a) FROM t1\n"
 | 
|      " WHERE b BETWEEN ?1 AND ?2; -- %d times", n
 | 
|    );
 | 
|    for(i=1; i<=n; i++){
 | 
| -    x1 = speedtest1_random()%maxb;
 | 
| -    x2 = speedtest1_random()%10 + sz/5000 + x1;
 | 
| +    if( (i-1)%g.nRepeat==0 ){
 | 
| +      x1 = speedtest1_random()%maxb;
 | 
| +      x2 = speedtest1_random()%10 + sz/5000 + x1;
 | 
| +    }
 | 
|      sqlite3_bind_int(g.pStmt, 1, x1);
 | 
|      sqlite3_bind_int(g.pStmt, 2, x2);
 | 
|      speedtest1_run();
 | 
| @@ -620,12 +714,14 @@ void testset_main(void){
 | 
|    speedtest1_begin_test(161, "%d SELECTS, numeric BETWEEN, PK", n);
 | 
|    speedtest1_exec("BEGIN");
 | 
|    speedtest1_prepare(
 | 
| -    "SELECT count(*), avg(b), sum(length(c)) FROM t2\n"
 | 
| +    "SELECT count(*), avg(b), sum(length(c)), group_concat(a) FROM t2\n"
 | 
|      " WHERE a BETWEEN ?1 AND ?2; -- %d times", n
 | 
|    );
 | 
|    for(i=1; i<=n; i++){
 | 
| -    x1 = speedtest1_random()%maxb;
 | 
| -    x2 = speedtest1_random()%10 + sz/5000 + x1;
 | 
| +    if( (i-1)%g.nRepeat==0 ){
 | 
| +      x1 = speedtest1_random()%maxb;
 | 
| +      x2 = speedtest1_random()%10 + sz/5000 + x1;
 | 
| +    }
 | 
|      sqlite3_bind_int(g.pStmt, 1, x1);
 | 
|      sqlite3_bind_int(g.pStmt, 2, x2);
 | 
|      speedtest1_run();
 | 
| @@ -638,12 +734,14 @@ void testset_main(void){
 | 
|    speedtest1_begin_test(170, "%d SELECTS, text BETWEEN, indexed", n);
 | 
|    speedtest1_exec("BEGIN");
 | 
|    speedtest1_prepare(
 | 
| -    "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
 | 
| +    "SELECT count(*), avg(b), sum(length(c)), group_concat(a) FROM t1\n"
 | 
|      " WHERE c BETWEEN ?1 AND (?1||'~'); -- %d times", n
 | 
|    );
 | 
|    for(i=1; i<=n; i++){
 | 
| -    x1 = swizzle(i, maxb);
 | 
| -    len = speedtest1_numbername(x1, zNum, sizeof(zNum)-1);
 | 
| +    if( (i-1)%g.nRepeat==0 ){
 | 
| +      x1 = swizzle(i, maxb);
 | 
| +      len = speedtest1_numbername(x1, zNum, sizeof(zNum)-1);
 | 
| +    }
 | 
|      sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
 | 
|      speedtest1_run();
 | 
|    }
 | 
| @@ -654,12 +752,12 @@ void testset_main(void){
 | 
|    speedtest1_begin_test(180, "%d INSERTS with three indexes", n);
 | 
|    speedtest1_exec("BEGIN");
 | 
|    speedtest1_exec(
 | 
| -    "CREATE TABLE t4(\n"
 | 
| +    "CREATE%s TABLE t4(\n"
 | 
|      "  a INTEGER %s %s,\n"
 | 
|      "  b INTEGER %s,\n"
 | 
|      "  c TEXT %s\n"
 | 
|      ") %s",
 | 
| -    g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
 | 
| +    isTemp(1), g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
 | 
|    speedtest1_exec("CREATE INDEX t4b ON t4(b)");
 | 
|    speedtest1_exec("CREATE INDEX t4c ON t4(c)");
 | 
|    speedtest1_exec("INSERT INTO t4 SELECT * FROM t1");
 | 
| @@ -802,6 +900,65 @@ void testset_main(void){
 | 
|    speedtest1_run();
 | 
|    speedtest1_end_test();
 | 
|  
 | 
| +  sz = n = g.szTest*700;
 | 
| +  zNum[0] = 0;
 | 
| +  maxb = roundup_allones(sz/3);
 | 
| +  speedtest1_begin_test(400, "%d REPLACE ops on an IPK", n);
 | 
| +  speedtest1_exec("BEGIN");
 | 
| +  speedtest1_exec("CREATE%s TABLE t5(a INTEGER PRIMARY KEY, b %s);",
 | 
| +                  isTemp(9), g.zNN);
 | 
| +  speedtest1_prepare("REPLACE INTO t5 VALUES(?1,?2); --  %d times",n);
 | 
| +  for(i=1; i<=n; i++){
 | 
| +    x1 = swizzle(i,maxb);
 | 
| +    speedtest1_numbername(i, zNum, sizeof(zNum));
 | 
| +    sqlite3_bind_int(g.pStmt, 1, (sqlite3_int64)x1);
 | 
| +    sqlite3_bind_text(g.pStmt, 2, zNum, -1, SQLITE_STATIC);
 | 
| +    speedtest1_run();
 | 
| +  }
 | 
| +  speedtest1_exec("COMMIT");
 | 
| +  speedtest1_end_test();
 | 
| +  speedtest1_begin_test(410, "%d SELECTS on an IPK", n);
 | 
| +  speedtest1_prepare("SELECT b FROM t5 WHERE a=?1; --  %d times",n);
 | 
| +  for(i=1; i<=n; i++){
 | 
| +    x1 = swizzle(i,maxb);
 | 
| +    sqlite3_bind_int(g.pStmt, 1, (sqlite3_int64)x1);
 | 
| +    speedtest1_run();
 | 
| +  }
 | 
| +  speedtest1_end_test();
 | 
| +
 | 
| +  sz = n = g.szTest*700;
 | 
| +  zNum[0] = 0;
 | 
| +  maxb = roundup_allones(sz/3);
 | 
| +  speedtest1_begin_test(500, "%d REPLACE on TEXT PK", n);
 | 
| +  speedtest1_exec("BEGIN");
 | 
| +  speedtest1_exec("CREATE%s TABLE t6(a TEXT PRIMARY KEY, b %s)%s;",
 | 
| +                  isTemp(9), g.zNN,
 | 
| +                  sqlite3_libversion_number()>=3008002 ? "WITHOUT ROWID" : "");
 | 
| +  speedtest1_prepare("REPLACE INTO t6 VALUES(?1,?2); --  %d times",n);
 | 
| +  for(i=1; i<=n; i++){
 | 
| +    x1 = swizzle(i,maxb);
 | 
| +    speedtest1_numbername(x1, zNum, sizeof(zNum));
 | 
| +    sqlite3_bind_int(g.pStmt, 2, i);
 | 
| +    sqlite3_bind_text(g.pStmt, 1, zNum, -1, SQLITE_STATIC);
 | 
| +    speedtest1_run();
 | 
| +  }
 | 
| +  speedtest1_exec("COMMIT");
 | 
| +  speedtest1_end_test();
 | 
| +  speedtest1_begin_test(510, "%d SELECTS on a TEXT PK", n);
 | 
| +  speedtest1_prepare("SELECT b FROM t6 WHERE a=?1; --  %d times",n);
 | 
| +  for(i=1; i<=n; i++){
 | 
| +    x1 = swizzle(i,maxb);
 | 
| +    speedtest1_numbername(x1, zNum, sizeof(zNum));
 | 
| +    sqlite3_bind_text(g.pStmt, 1, zNum, -1, SQLITE_STATIC);
 | 
| +    speedtest1_run();
 | 
| +  }
 | 
| +  speedtest1_end_test();
 | 
| +  speedtest1_begin_test(520, "%d SELECT DISTINCT", n);
 | 
| +  speedtest1_exec("SELECT DISTINCT b FROM t5;");
 | 
| +  speedtest1_exec("SELECT DISTINCT b FROM t6;");
 | 
| +  speedtest1_end_test();
 | 
| +
 | 
| +
 | 
|    speedtest1_begin_test(980, "PRAGMA integrity_check");
 | 
|    speedtest1_exec("PRAGMA integrity_check");
 | 
|    speedtest1_end_test();
 | 
| @@ -1021,10 +1178,10 @@ void testset_rtree(int p1, int p2){
 | 
|    unsigned mxCoord;
 | 
|    unsigned x0, x1, y0, y1, z0, z1;
 | 
|    unsigned iStep;
 | 
| -  int *aCheck = sqlite3_malloc( sizeof(int)*g.szTest*100 );
 | 
| +  int *aCheck = sqlite3_malloc( sizeof(int)*g.szTest*500 );
 | 
|  
 | 
|    mxCoord = 15000;
 | 
| -  n = g.szTest*100;
 | 
| +  n = g.szTest*500;
 | 
|    speedtest1_begin_test(100, "%d INSERTs into an r-tree", n);
 | 
|    speedtest1_exec("BEGIN");
 | 
|    speedtest1_exec("CREATE VIRTUAL TABLE rt1 USING rtree(id,x0,x1,y0,y1,z0,z1)");
 | 
| @@ -1051,7 +1208,7 @@ void testset_rtree(int p1, int p2){
 | 
|    speedtest1_exec("INSERT INTO t1 SELECT * FROM rt1");
 | 
|    speedtest1_end_test();
 | 
|  
 | 
| -  n = g.szTest*20;
 | 
| +  n = g.szTest*100;
 | 
|    speedtest1_begin_test(110, "%d one-dimensional intersect slice queries", n);
 | 
|    speedtest1_prepare("SELECT count(*) FROM rt1 WHERE x0>=?1 AND x1<=?2");
 | 
|    iStep = mxCoord/n;
 | 
| @@ -1064,7 +1221,7 @@ void testset_rtree(int p1, int p2){
 | 
|    speedtest1_end_test();
 | 
|  
 | 
|    if( g.bVerify ){
 | 
| -    n = g.szTest*20;
 | 
| +    n = g.szTest*100;
 | 
|      speedtest1_begin_test(111, "Verify result from 1-D intersect slice queries");
 | 
|      speedtest1_prepare("SELECT count(*) FROM t1 WHERE x0>=?1 AND x1<=?2");
 | 
|      iStep = mxCoord/n;
 | 
| @@ -1080,7 +1237,7 @@ void testset_rtree(int p1, int p2){
 | 
|      speedtest1_end_test();
 | 
|    }
 | 
|    
 | 
| -  n = g.szTest*20;
 | 
| +  n = g.szTest*100;
 | 
|    speedtest1_begin_test(120, "%d one-dimensional overlap slice queries", n);
 | 
|    speedtest1_prepare("SELECT count(*) FROM rt1 WHERE y1>=?1 AND y0<=?2");
 | 
|    iStep = mxCoord/n;
 | 
| @@ -1093,7 +1250,7 @@ void testset_rtree(int p1, int p2){
 | 
|    speedtest1_end_test();
 | 
|  
 | 
|    if( g.bVerify ){
 | 
| -    n = g.szTest*20;
 | 
| +    n = g.szTest*100;
 | 
|      speedtest1_begin_test(121, "Verify result from 1-D overlap slice queries");
 | 
|      speedtest1_prepare("SELECT count(*) FROM t1 WHERE y1>=?1 AND y0<=?2");
 | 
|      iStep = mxCoord/n;
 | 
| @@ -1110,7 +1267,7 @@ void testset_rtree(int p1, int p2){
 | 
|    }
 | 
|    
 | 
|  
 | 
| -  n = g.szTest*20;
 | 
| +  n = g.szTest*100;
 | 
|    speedtest1_begin_test(125, "%d custom geometry callback queries", n);
 | 
|    sqlite3_rtree_geometry_callback(g.db, "xslice", xsliceGeometryCallback, 0);
 | 
|    speedtest1_prepare("SELECT count(*) FROM rt1 WHERE id MATCH xslice(?1,?2)");
 | 
| @@ -1126,7 +1283,7 @@ void testset_rtree(int p1, int p2){
 | 
|    }
 | 
|    speedtest1_end_test();
 | 
|  
 | 
| -  n = g.szTest*80;
 | 
| +  n = g.szTest*400;
 | 
|    speedtest1_begin_test(130, "%d three-dimensional intersect box queries", n);
 | 
|    speedtest1_prepare("SELECT count(*) FROM rt1 WHERE x1>=?1 AND x0<=?2"
 | 
|                       " AND y1>=?1 AND y0<=?2 AND z1>=?1 AND z0<=?2");
 | 
| @@ -1139,7 +1296,7 @@ void testset_rtree(int p1, int p2){
 | 
|    }
 | 
|    speedtest1_end_test();
 | 
|  
 | 
| -  n = g.szTest*100;
 | 
| +  n = g.szTest*500;
 | 
|    speedtest1_begin_test(140, "%d rowid queries", n);
 | 
|    speedtest1_prepare("SELECT * FROM rt1 WHERE id=?1");
 | 
|    for(i=1; i<=n; i++){
 | 
| @@ -1167,6 +1324,49 @@ void testset_debug1(void){
 | 
|    }
 | 
|  }
 | 
|  
 | 
| +#ifdef __linux__
 | 
| +#include <sys/types.h>
 | 
| +#include <unistd.h>
 | 
| +
 | 
| +/*
 | 
| +** Attempt to display I/O stats on Linux using /proc/PID/io
 | 
| +*/
 | 
| +static void displayLinuxIoStats(FILE *out){
 | 
| +  FILE *in;
 | 
| +  char z[200];
 | 
| +  sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
 | 
| +  in = fopen(z, "rb");
 | 
| +  if( in==0 ) return;
 | 
| +  while( fgets(z, sizeof(z), in)!=0 ){
 | 
| +    static const struct {
 | 
| +      const char *zPattern;
 | 
| +      const char *zDesc;
 | 
| +    } aTrans[] = {
 | 
| +      { "rchar: ",                  "Bytes received by read():" },
 | 
| +      { "wchar: ",                  "Bytes sent to write():"    },
 | 
| +      { "syscr: ",                  "Read() system calls:"      },
 | 
| +      { "syscw: ",                  "Write() system calls:"     },
 | 
| +      { "read_bytes: ",             "Bytes rcvd from storage:"  },
 | 
| +      { "write_bytes: ",            "Bytes sent to storage:"    },
 | 
| +      { "cancelled_write_bytes: ",  "Cancelled write bytes:"    },
 | 
| +    };
 | 
| +    int i;
 | 
| +    for(i=0; i<sizeof(aTrans)/sizeof(aTrans[0]); i++){
 | 
| +      int n = (int)strlen(aTrans[i].zPattern);
 | 
| +      if( strncmp(aTrans[i].zPattern, z, n)==0 ){
 | 
| +        fprintf(out, "-- %-28s %s", aTrans[i].zDesc, &z[n]);
 | 
| +        break;
 | 
| +      }
 | 
| +    }
 | 
| +  }
 | 
| +  fclose(in);
 | 
| +}   
 | 
| +#endif
 | 
| +
 | 
| +#if SQLITE_VERSION_NUMBER<3006018
 | 
| +#  define sqlite3_sourceid(X) "(before 3.6.18)"
 | 
| +#endif
 | 
| +
 | 
|  int main(int argc, char **argv){
 | 
|    int doAutovac = 0;            /* True for --autovacuum */
 | 
|    int cacheSize = 0;            /* Desired cache size.  0 means default */
 | 
| @@ -1175,7 +1375,7 @@ int main(int argc, char **argv){
 | 
|    int doIncrvac = 0;            /* True for --incrvacuum */
 | 
|    const char *zJMode = 0;       /* Journal mode */
 | 
|    const char *zKey = 0;         /* Encryption key */
 | 
| -  int nLook = 0, szLook = 0;    /* --lookaside configuration */
 | 
| +  int nLook = -1, szLook = 0;   /* --lookaside configuration */
 | 
|    int noSync = 0;               /* True for --nosync */
 | 
|    int pageSize = 0;             /* Desired page size.  0 means default */
 | 
|    int nPCache = 0, szPCache = 0;/* --pcache configuration */
 | 
| @@ -1183,6 +1383,7 @@ int main(int argc, char **argv){
 | 
|    int nScratch = 0, szScratch=0;/* --scratch configuration */
 | 
|    int showStats = 0;            /* True for --stats */
 | 
|    int nThread = 0;              /* --threads value */
 | 
| +  int mmapSize = 0;             /* How big of a memory map to use */
 | 
|    const char *zTSet = "main";   /* Which --testset torun */
 | 
|    int doTrace = 0;              /* True for --trace */
 | 
|    const char *zEncoding = 0;    /* --utf16be or --utf16le */
 | 
| @@ -1196,11 +1397,16 @@ int main(int argc, char **argv){
 | 
|    int i;                        /* Loop counter */
 | 
|    int rc;                       /* API return code */
 | 
|  
 | 
| +  /* Display the version of SQLite being tested */
 | 
| +  printf("-- Speedtest1 for SQLite %s %.50s\n",
 | 
| +         sqlite3_libversion(), sqlite3_sourceid());
 | 
| +
 | 
|    /* Process command-line arguments */
 | 
|    g.zWR = "";
 | 
|    g.zNN = "";
 | 
|    g.zPK = "UNIQUE";
 | 
|    g.szTest = 100;
 | 
| +  g.nRepeat = 1;
 | 
|    for(i=1; i<argc; i++){
 | 
|      const char *z = argv[i];
 | 
|      if( z[0]=='-' ){
 | 
| @@ -1234,19 +1440,21 @@ int main(int argc, char **argv){
 | 
|          nLook = integerValue(argv[i+1]);
 | 
|          szLook = integerValue(argv[i+2]);
 | 
|          i += 2;
 | 
| +#if SQLITE_VERSION_NUMBER>=3006000
 | 
|        }else if( strcmp(z,"multithread")==0 ){
 | 
|          sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
 | 
|        }else if( strcmp(z,"nomemstat")==0 ){
 | 
|          sqlite3_config(SQLITE_CONFIG_MEMSTATUS, 0);
 | 
| +#endif
 | 
| +#if SQLITE_VERSION_NUMBER>=3007017
 | 
| +      }else if( strcmp(z, "mmap")==0 ){
 | 
| +        if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
 | 
| +        mmapSize = integerValue(argv[++i]);
 | 
| + #endif
 | 
|        }else if( strcmp(z,"nosync")==0 ){
 | 
|          noSync = 1;
 | 
|        }else if( strcmp(z,"notnull")==0 ){
 | 
|          g.zNN = "NOT NULL";
 | 
| -#ifdef SQLITE_ENABLE_RBU
 | 
| -      }else if( strcmp(z,"rbu")==0 ){
 | 
| -        sqlite3ota_create_vfs("rbu", 0);
 | 
| -        sqlite3_vfs_register(sqlite3_vfs_find("rbu"), 1);
 | 
| -#endif
 | 
|        }else if( strcmp(z,"pagesize")==0 ){
 | 
|          if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
 | 
|          pageSize = integerValue(argv[++i]);
 | 
| @@ -1258,6 +1466,10 @@ int main(int argc, char **argv){
 | 
|          i += 2;
 | 
|        }else if( strcmp(z,"primarykey")==0 ){
 | 
|          g.zPK = "PRIMARY KEY";
 | 
| +      }else if( strcmp(z,"repeat")==0 ){
 | 
| +        if( i>=argc-1 ) fatal_error("missing arguments on %s\n", argv[i]);
 | 
| +        g.nRepeat = integerValue(argv[i+1]);
 | 
| +        i += 1;
 | 
|        }else if( strcmp(z,"reprepare")==0 ){
 | 
|          g.bReprepare = 1;
 | 
|        }else if( strcmp(z,"scratch")==0 ){
 | 
| @@ -1265,10 +1477,12 @@ int main(int argc, char **argv){
 | 
|          nScratch = integerValue(argv[i+1]);
 | 
|          szScratch = integerValue(argv[i+2]);
 | 
|          i += 2;
 | 
| +#if SQLITE_VERSION_NUMBER>=3006000
 | 
|        }else if( strcmp(z,"serialized")==0 ){
 | 
|          sqlite3_config(SQLITE_CONFIG_SERIALIZED);
 | 
|        }else if( strcmp(z,"singlethread")==0 ){
 | 
|          sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
 | 
| +#endif
 | 
|        }else if( strcmp(z,"sqlonly")==0 ){
 | 
|          g.bSqlOnly = 1;
 | 
|        }else if( strcmp(z,"shrink-memory")==0 ){
 | 
| @@ -1278,6 +1492,13 @@ int main(int argc, char **argv){
 | 
|          g.szTest = integerValue(argv[++i]);
 | 
|        }else if( strcmp(z,"stats")==0 ){
 | 
|          showStats = 1;
 | 
| +      }else if( strcmp(z,"temp")==0 ){
 | 
| +        if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
 | 
| +        i++;
 | 
| +        if( argv[i][0]<'0' || argv[i][0]>'9' || argv[i][1]!=0 ){
 | 
| +          fatal_error("argument to --temp should be integer between 0 and 9");
 | 
| +        }
 | 
| +        g.eTemp = argv[i][0] - '0';
 | 
|        }else if( strcmp(z,"testset")==0 ){
 | 
|          if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
 | 
|          zTSet = argv[++i];
 | 
| @@ -1309,11 +1530,7 @@ int main(int argc, char **argv){
 | 
|                    argv[i], argv[0]);
 | 
|      }
 | 
|    }
 | 
| -#if 0
 | 
| -  if( zDbName==0 ){
 | 
| -    fatal_error(zHelp, argv[0]);
 | 
| -  }
 | 
| -#endif
 | 
| +  if( zDbName!=0 ) unlink(zDbName);
 | 
|  #if SQLITE_VERSION_NUMBER>=3006001
 | 
|    if( nHeap>0 ){
 | 
|      pHeap = malloc( nHeap );
 | 
| @@ -1337,7 +1554,7 @@ int main(int argc, char **argv){
 | 
|      rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, pScratch, szScratch, nScratch);
 | 
|      if( rc ) fatal_error("scratch configuration failed: %d\n", rc);
 | 
|    }
 | 
| -  if( nLook>0 ){
 | 
| +  if( nLook>=0 ){
 | 
|      sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);
 | 
|    }
 | 
|  #endif
 | 
| @@ -1356,7 +1573,12 @@ int main(int argc, char **argv){
 | 
|  
 | 
|    /* Set database connection options */
 | 
|    sqlite3_create_function(g.db, "random", 0, SQLITE_UTF8, 0, randomFunc, 0, 0);
 | 
| +#ifndef SQLITE_OMIT_DEPRECATED
 | 
|    if( doTrace ) sqlite3_trace(g.db, traceCallback, 0);
 | 
| +#endif
 | 
| +  if( mmapSize>0 ){
 | 
| +    speedtest1_exec("PRAGMA mmap_size=%d", mmapSize);
 | 
| +  }
 | 
|    speedtest1_exec("PRAGMA threads=%d", nThread);
 | 
|    if( zKey ){
 | 
|      speedtest1_exec("PRAGMA key('%s')", zKey);
 | 
| @@ -1457,6 +1679,12 @@ int main(int argc, char **argv){
 | 
|    }
 | 
|  #endif
 | 
|  
 | 
| +#ifdef __linux__
 | 
| +  if( showStats ){
 | 
| +    displayLinuxIoStats(stdout);
 | 
| +  }
 | 
| +#endif
 | 
| +
 | 
|    /* Release memory */
 | 
|    free( pLook );
 | 
|    free( pPCache );
 | 
| 
 |