]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the ability to turn of calls to fsync() using the "synchronous" pragma.
authordrh <drh@noemail.net>
Tue, 5 Mar 2002 01:11:12 +0000 (01:11 +0000)
committerdrh <drh@noemail.net>
Tue, 5 Mar 2002 01:11:12 +0000 (01:11 +0000)
Increased the default cache size from 100 to 2000 and made the "cache_size"
pragma persistent. (CVS 418)

FossilOrigin-Name: 414da4af1f4aebc3936ca339fbc7932add081912

manifest
manifest.uuid
src/build.c
src/main.c
src/os.c
src/pager.c
src/parse.y
src/sqliteInt.h
src/vdbe.c
tool/speedtest.tcl [new file with mode: 0644]
www/changes.tcl

index 97c0748af1cf0845f460bdac4d8cd21cf0471368..5c6840dc7ba84606b0677a8c5107018840c38fbb 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Updates\sto\sthe\sdocumentation.\s\sChanged\sversion\snumber\sto\s2.4.0-beta1\s(CVS\s417)
-D 2002-03-04T02:26:16
+C Add\sthe\sability\sto\sturn\sof\scalls\sto\sfsync()\susing\sthe\s"synchronous"\spragma.\nIncreased\sthe\sdefault\scache\ssize\sfrom\s100\sto\s2000\sand\smade\sthe\s"cache_size"\npragma\spersistent.\s(CVS\s418)
+D 2002-03-05T01:11:13
 F Makefile.in 50f1b3351df109b5774771350d8c1b8d3640130d
 F Makefile.template 89e373b2dad0321df00400fa968dc14b61a03296
 F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
@@ -21,27 +21,27 @@ F sqlite.1 2e2bb0529ef468ade9e4322bd609d0695fb9ded9
 F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
 F src/btree.c d25ea795a0f7017bc2099c437e6cc01d4c31b22d
 F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3
-F src/build.c e11b0daa79ba894c7476c33372b1dc42b13471e6
+F src/build.c 0f3c6b6482e0b74284b22661de1b813a0bfb0197
 F src/delete.c 577da499162291c1855f0b304b211bffcf9da945
 F src/expr.c e12ca550536c0bae7a3acef49dfa3068fe5f0900
 F src/func.c 87516e7dc37190c24af77593931a5d09d797520a
 F src/hash.c cc259475e358baaf299b00a2c7370f2b03dda892
 F src/hash.h dca065dda89d4575f3176e75e9a3dc0f4b4fb8b9
 F src/insert.c 42bfd145efd428d7e5f200dd49ea0b816fc30d79
-F src/main.c 5651146585ae613e759fcf372ee064e4940c2463
+F src/main.c 3015c23faeff1709b1528f07c0bfe839284090a8
 F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
-F src/os.c f6bc9b7ab530346bb7fef2ed39f2f1f214bc14ea
+F src/os.c db969ecd1bcb4fef01b0b541b8b17401b0eb7ed2
 F src/os.h a17596ecc7f38a228b83ecdb661fb03ce44726d6
-F src/pager.c 0aa358a378c416ee0b0be5bf03fa7c35f7992c9b
+F src/pager.c 41af87908cd76a50d7e22cf3c7a4d479e3c9a512
 F src/pager.h feb18aab2f6dea439393f23a382699b9b1053c32
-F src/parse.y 25b794bfbed2a68d13d7d40a986a0ebe2beb3e24
+F src/parse.y f7483ccff7b8f16d3655df59775d85b62b06897e
 F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d
 F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
 F src/select.c 49c78aa0c96dda036846937b516658536db98b56
 F src/shell.c b3454229599246b944cdb5b95753af3fca5d8bb0
 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
 F src/sqlite.h.in a9b5772604265f98f3120573ef29e37b9d917216
-F src/sqliteInt.h dde4e52e234e54e8ac9d3a1964e93c5fa6c2de15
+F src/sqliteInt.h 46f41e2f4cf90cdbe002f6b4143ae3f16ae0b872
 F src/table.c 203a09d5d0009eeeb1f670370d52b4ce163a3b52
 F src/tclsqlite.c b9cf346e95291cb4c4f1bf5ac1d77db6b8ad023d
 F src/test1.c 33efd350dca27c52c58c553c04fd3a6a51f13c1f
@@ -51,7 +51,7 @@ F src/threadtest.c 81f0598e0f031c1bd506af337fdc1b7e8dff263f
 F src/tokenize.c 4b5d30590a744b9bb5605a92d1f620ab2e7e75af
 F src/update.c 7dd714a6a7fa47f849ebb36b6d915974d6c6accb
 F src/util.c 00a35b421c92ae0d7cfa51bd87f7d4995f464d19
-F src/vdbe.c 4989cd3e6f4f699c9b08cd1980d1b588cede5c1f
+F src/vdbe.c 0b634bbe3d1a770136b9f7324804bb55903a9b17
 F src/vdbe.h f9be1f6e9a336c3ff4d14ea7489ee976e07460cc
 F src/where.c 34d91fd5d822c2663caeb023f72d60df316ebf29
 F test/all.test 7a8a8a7a579ed2bb4d8976d55402f21eacd58049
@@ -108,11 +108,12 @@ F tool/opNames.awk 5ba1f48aa854ee3b7c3d2b54233665bc3e649ea2
 F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
 F tool/renumberOps.awk 6d067177ad5f8d711b79577b462da9b3634bd0a9
 F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816
+F tool/speedtest.tcl 31a2f06e3d2153f4311b13cd6fd5e19b7adc8373
 F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
 F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
 F www/arch.tcl 72a0c80e9054cc7025a50928d28d9c75c02c2b8b
 F www/c_interface.tcl 567cda531aac9d68a61ef02e26c6b202bd856db2
-F www/changes.tcl cdd351b0f358bc23ca6243f3ca52c35ca1bede26
+F www/changes.tcl b43d9e32ed7af9a93c5a9b7321abe2ee6a8f4ea9
 F www/conflict.tcl 81dd21f9a679e60aae049e9dd8ab53d59570cda2
 F www/crosscompile.tcl 3622ebbe518927a3854a12de51344673eb2dd060
 F www/download.tcl a6d75b8b117cd33dcb090bef7e80d7556d28ebe0
@@ -127,7 +128,7 @@ F www/speed.tcl 83457b2bf6bb430900bd48ca3dd98264d9a916a5
 F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
 F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49
 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P 813077623087ffc6cd506f57cf6d1e3d9239f806
-R fe676fb38cbe5a2068c89e56308a155d
+P 36a8fe0ad0ee2a67afafc04125dcc085ec1b5a13
+R e93330a0aa7a7fa6a56e7a5c31b63757
 U drh
-Z 9a81a81e1e363e5bb6c841e14ddef308
+Z b84940384f009522e2520b7d71139ff4
index 79e1438fa4734215612b8d0ca6a49e1f894c63fb..36d2035611d9d588b57c0d3c31ce590ae5aa9036 100644 (file)
@@ -1 +1 @@
-36a8fe0ad0ee2a67afafc04125dcc085ec1b5a13
\ No newline at end of file
+414da4af1f4aebc3936ca339fbc7932add081912
\ No newline at end of file
index 1642e47eb80464d26b5b44cdaeae04490d61bc2c..639ba00f7ae272eca38f0d262f7af7ef8b6e6d55 100644 (file)
@@ -25,7 +25,7 @@
 **     ROLLBACK
 **     PRAGMA
 **
-** $Id: build.c,v 1.84 2002/03/04 02:26:16 drh Exp $
+** $Id: build.c,v 1.85 2002/03/05 01:11:13 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -423,7 +423,8 @@ void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName, int isTemp){
   if( !pParse->initFlag && (v = sqliteGetVdbe(pParse))!=0 ){
     sqliteBeginWriteOperation(pParse);
     if( !isTemp ){
-      sqliteVdbeAddOp(v, OP_SetCookie, db->file_format, 1);
+      sqliteVdbeAddOp(v, OP_Integer, db->file_format, 0);
+      sqliteVdbeAddOp(v, OP_SetCookie, 0, 1);
       sqliteVdbeAddOp(v, OP_OpenWrite, 0, 2);
       sqliteVdbeChangeP3(v, -1, MASTER_NAME, P3_STATIC);
       sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
@@ -794,7 +795,8 @@ void sqliteEndTable(Parse *pParse, Token *pEnd, Select *pSelect){
       sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0);
       sqliteVdbeAddOp(v, OP_PutIntKey, 0, 0);
       changeCookie(db);
-      sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0);
+      sqliteVdbeAddOp(v, OP_Integer, db->next_cookie, 0);
+      sqliteVdbeAddOp(v, OP_SetCookie, 0, 0);
       sqliteVdbeAddOp(v, OP_Close, 0, 0);
     }
     if( pSelect ){
@@ -1023,7 +1025,8 @@ void sqliteDropTable(Parse *pParse, Token *pName, int isView){
       { OP_Ne,         0, ADDR(8),  0},
       { OP_Delete,     0, 0,        0},
       { OP_Next,       0, ADDR(4),  0}, /* 8 */
-      { OP_SetCookie,  0, 0,        0}, /* 9 */
+      { OP_Integer,    0, 0,        0}, /* 9 */
+      { OP_SetCookie,  0, 0,        0},
       { OP_Close,      0, 0,        0},
     };
     Index *pIdx;
@@ -1337,7 +1340,8 @@ void sqliteCreateIndex(
     if( pTable!=0 ){
       if( !isTemp ){
         changeCookie(db);
-        sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0);
+        sqliteVdbeAddOp(v, OP_Integer, db->next_cookie, 0);
+        sqliteVdbeAddOp(v, OP_SetCookie, 0, 0);
         sqliteVdbeAddOp(v, OP_Close, 0, 0);
       }
       sqliteEndWriteOperation(pParse);
@@ -1387,7 +1391,8 @@ void sqliteDropIndex(Parse *pParse, Token *pName){
       { OP_Next,       0, ADDR(4), 0},
       { OP_Goto,       0, ADDR(10),0},
       { OP_Delete,     0, 0,       0}, /* 9 */
-      { OP_SetCookie,  0, 0,       0}, /* 10 */
+      { OP_Integer,    0, 0,       0}, /* 10 */
+      { OP_SetCookie,  0, 0,       0},
       { OP_Close,      0, 0,       0},
     };
     int base;
@@ -1732,8 +1737,58 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
   }
  
   if( sqliteStrICmp(zLeft,"cache_size")==0 ){
-    int size = atoi(zRight);
-    sqliteBtreeSetCacheSize(db->pBe, size);
+    static VdbeOp getCacheSize[] = {
+      { OP_ReadCookie,  0, 2,        0},
+      { OP_AbsValue,    0, 0,        0},
+      { OP_ColumnCount, 1, 0,        0},
+      { OP_ColumnName,  0, 0,        "cache_size"},
+      { OP_Callback,    1, 0,        0},
+    };
+    Vdbe *v = sqliteGetVdbe(pParse);
+    if( v==0 ) return;
+    if( pRight->z==pLeft->z ){
+      sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
+    }else{
+      int addr;
+      int size = atoi(zRight);
+      if( size<0 ) size = -size;
+      sqliteBeginWriteOperation(pParse);
+      sqliteVdbeAddOp(v, OP_Integer, size, 0);
+      sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);
+      addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0);
+      sqliteVdbeAddOp(v, OP_Ge, 0, addr+3);
+      sqliteVdbeAddOp(v, OP_Negative, 0, 0);
+      sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);
+      sqliteEndWriteOperation(pParse);
+    }
+  }else
+
+  if( sqliteStrICmp(zLeft,"synchronous")==0 ){
+    static VdbeOp getSync[] = {
+      { OP_Integer,     0, 0,        0},
+      { OP_ReadCookie,  0, 2,        0},
+      { OP_Integer,     0, 0,        0},
+      { OP_Lt,          0, 5,        0},
+      { OP_AddImm,      1, 0,        0},
+      { OP_ColumnCount, 1, 0,        0},
+      { OP_ColumnName,  0, 0,        "synchronous"},
+      { OP_Callback,    1, 0,        0},
+    };
+    Vdbe *v = sqliteGetVdbe(pParse);
+    if( v==0 ) return;
+    if( pRight->z==pLeft->z ){
+      sqliteVdbeAddOpList(v, ArraySize(getSync), getSync);
+    }else{
+      int addr;
+      sqliteBeginWriteOperation(pParse);
+      sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);
+      sqliteVdbeAddOp(v, OP_AbsValue, 0, 0);
+      if( !getBoolean(zRight) ){
+        sqliteVdbeAddOp(v, OP_Negative, 0, 0);
+      }
+      sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);
+      sqliteEndWriteOperation(pParse);
+    }
   }else
 
   if( sqliteStrICmp(zLeft, "vdbe_trace")==0 ){
index 8ad0d18d32c450322419a1370e7b66b392cd643f..62f0952a3ab634beacade32b7082fb544efc9ec5 100644 (file)
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.66 2002/02/28 00:41:11 drh Exp $
+** $Id: main.c,v 1.67 2002/03/05 01:11:14 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -42,6 +42,13 @@ static int sqliteOpenCb(void *pDb, int argc, char **argv, char **azColName){
 
   assert( argc==4 );
   switch( argv[0][0] ){
+    case 'c': {  /* Recommended pager cache size */
+      int size = atoi(argv[3]);
+      if( size!=0 ){
+        sqliteBtreeSetCacheSize(db->pBe, size);
+      }
+      break;
+    }
     case 'f': {  /* File format */
       db->file_format = atoi(argv[3]);
       break;
@@ -176,6 +183,14 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){
     { OP_ReadCookie, 0, 1,  0},
     { OP_Callback,   4, 0,  0},
 
+    /* Send the recommended pager cache size to the callback routine
+    */
+    { OP_String,     0, 0,  "cache-size"},
+    { OP_String,     0, 0,  0},
+    { OP_String,     0, 0,  0},
+    { OP_ReadCookie, 0, 2,  0},
+    { OP_Callback,   4, 0,  0},
+
     /* Send the initial schema cookie to the callback
     */
     { OP_String,     0, 0,  "schema_cookie"},
@@ -192,45 +207,45 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){
     */
     { OP_ReadCookie, 0, 1,  0},
     { OP_Integer,    2, 0,  0},
-    { OP_Lt,         0, 23, 0},
+    { OP_Lt,         0, 28, 0},
 
     /* This is the code for doing a single scan through the SQLITE_MASTER
     ** table.  This code runs for format 2 and greater.
     */
-    { OP_Rewind,     0, 21, 0},
-    { OP_Column,     0, 0,  0},           /* 15 */
+    { OP_Rewind,     0, 26, 0},
+    { OP_Column,     0, 0,  0},           /* 20 */
     { OP_Column,     0, 1,  0},
     { OP_Column,     0, 3,  0},
     { OP_Column,     0, 4,  0},
     { OP_Callback,   4, 0,  0},
-    { OP_Next,       0, 15, 0},
-    { OP_Close,      0, 0,  0},           /* 21 */
+    { OP_Next,       0, 20, 0},
+    { OP_Close,      0, 0,  0},           /* 26 */
     { OP_Halt,       0, 0,  0},
 
     /* This is the code for doing two passes through SQLITE_MASTER.  This
     ** code runs for file format 1.
     */
-    { OP_Rewind,     0, 43, 0},           /* 23 */
-    { OP_Column,     0, 0,  0},           /* 24 */
+    { OP_Rewind,     0, 48, 0},           /* 28 */
+    { OP_Column,     0, 0,  0},           /* 29 */
     { OP_String,     0, 0,  "table"},
-    { OP_Ne,         0, 32, 0},
+    { OP_Ne,         0, 37, 0},
     { OP_Column,     0, 0,  0},
     { OP_Column,     0, 1,  0},
     { OP_Column,     0, 3,  0},
     { OP_Column,     0, 4,  0},
     { OP_Callback,   4, 0,  0},
-    { OP_Next,       0, 24, 0},           /* 32 */
-    { OP_Rewind,     0, 43, 0},           /* 33 */
-    { OP_Column,     0, 0,  0},           /* 34 */
+    { OP_Next,       0, 29, 0},           /* 37 */
+    { OP_Rewind,     0, 48, 0},           /* 38 */
+    { OP_Column,     0, 0,  0},           /* 39 */
     { OP_String,     0, 0,  "index"},
-    { OP_Ne,         0, 42, 0},
+    { OP_Ne,         0, 47, 0},
     { OP_Column,     0, 0,  0},
     { OP_Column,     0, 1,  0},
     { OP_Column,     0, 3,  0},
     { OP_Column,     0, 4,  0},
     { OP_Callback,   4, 0,  0},
-    { OP_Next,       0, 34, 0},           /* 42 */
-    { OP_Close,      0, 0,  0},           /* 43 */
+    { OP_Next,       0, 39, 0},           /* 47 */
+    { OP_Close,      0, 0,  0},           /* 48 */
     { OP_Halt,       0, 0,  0},
   };
 
index ae1368c2843c50cc16d00bd0316b612056062071..0467545822c58ae4254659f6ea380190569bf37c 100644 (file)
--- a/src/os.c
+++ b/src/os.c
 # include <winbase.h>
 #endif
 
+/*
+** Macros for performance tracing.  Normally turned off
+*/
+#if 0
+static int last_page = 0;
+#define SEEK(X)     last_page=(X)
+#define TRACE1(X)   fprintf(stderr,X)
+#define TRACE2(X,Y) fprintf(stderr,X,Y)
+#else
+#define SEEK(X)
+#define TRACE1(X)
+#define TRACE2(X,Y)
+#endif
+
 
 #if OS_UNIX
 /*
@@ -477,6 +491,7 @@ int sqliteOsRead(OsFile *id, void *pBuf, int amt){
 #if OS_UNIX
   int got;
   SimulateIOError(SQLITE_IOERR);
+  TRACE2("READ %d\n", last_page);
   got = read(id->fd, pBuf, amt);
   if( got<0 ) got = 0;
   return got==amt ? SQLITE_OK : SQLITE_IOERR;
@@ -499,6 +514,7 @@ int sqliteOsWrite(OsFile *id, const void *pBuf, int amt){
 #if OS_UNIX
   int wrote;
   SimulateIOError(SQLITE_IOERR);
+  TRACE2("WRITE %d\n", last_page);
   wrote = write(id->fd, pBuf, amt);
   if( wrote<amt ) return SQLITE_FULL;
   return SQLITE_OK;
@@ -517,6 +533,7 @@ int sqliteOsWrite(OsFile *id, const void *pBuf, int amt){
 ** Move the read/write pointer in a file.
 */
 int sqliteOsSeek(OsFile *id, int offset){
+  SEEK(offset/1024 + 1);
 #if OS_UNIX
   lseek(id->fd, offset, SEEK_SET);
   return SQLITE_OK;
@@ -532,6 +549,7 @@ int sqliteOsSeek(OsFile *id, int offset){
 */
 int sqliteOsSync(OsFile *id){
   SimulateIOError(SQLITE_IOERR);
+  TRACE1("SYNC\n");
 #if OS_UNIX
   return fsync(id->fd)==0 ? SQLITE_OK : SQLITE_IOERR;
 #endif
index b69b2832829ddc74bfc8eec000d08ee82a8097ff..de332cba02d1ae6ad207b7acd7c4accb53fae8b5 100644 (file)
@@ -18,7 +18,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.41 2002/03/02 20:41:59 drh Exp $
+** @(#) $Id: pager.c,v 1.42 2002/03/05 01:11:14 drh Exp $
 */
 #include "sqliteInt.h"
 #include "pager.h"
@@ -93,7 +93,7 @@ struct PgHdr {
 ** How big to make the hash table used for locating in-memory pages
 ** by page number.  Knuth says this should be a prime number.
 */
-#define N_PG_HASH 373
+#define N_PG_HASH 2003
 
 /*
 ** A open page cache is an instance of the following structure.
@@ -103,8 +103,6 @@ struct Pager {
   char *zJournal;             /* Name of the journal file */
   OsFile fd, jfd;             /* File descriptors for database and journal */
   OsFile cpfd;                /* File descriptor for the checkpoint journal */
-  int journalOpen;            /* True if journal file descriptors is valid */
-  int ckptOpen;               /* True if the checkpoint journal is open */
   int dbSize;                 /* Number of pages in the file */
   int origDbSize;             /* dbSize before the current change */
   int ckptSize, ckptJSize;    /* Size of database and journal at ckpt_begin() */
@@ -114,13 +112,16 @@ struct Pager {
   int nRef;                   /* Number of in-memory pages with PgHdr.nRef>0 */
   int mxPage;                 /* Maximum number of pages to hold in cache */
   int nHit, nMiss, nOvfl;     /* Cache hits, missing, and LRU overflows */
-  unsigned char state;        /* SQLITE_UNLOCK, _READLOCK or _WRITELOCK */
-  unsigned char errMask;      /* One of several kinds of errors */
-  unsigned char tempFile;     /* zFilename is a temporary file */
-  unsigned char readOnly;     /* True for a read-only database */
-  unsigned char needSync;     /* True if an fsync() is needed on the journal */
-  unsigned char *aInJournal;  /* One bit for each page in the database file */
-  unsigned char *aInCkpt;     /* One bit for each page in the database */
+  u8 journalOpen;             /* True if journal file descriptors is valid */
+  u8 ckptOpen;                /* True if the checkpoint journal is open */
+  u8 noSync;                  /* Do not sync the journal if true */
+  u8 state;                   /* SQLITE_UNLOCK, _READLOCK or _WRITELOCK */
+  u8 errMask;                 /* One of several kinds of errors */
+  u8 tempFile;                /* zFilename is a temporary file */
+  u8 readOnly;                /* True for a read-only database */
+  u8 needSync;                /* True if an fsync() is needed on the journal */
+  u8 *aInJournal;             /* One bit for each page in the database file */
+  u8 *aInCkpt;                /* One bit for each page in the database */
   PgHdr *pFirst, *pLast;      /* List of free pages */
   PgHdr *pAll;                /* List of all pages */
   PgHdr *aHash[N_PG_HASH];    /* Hash table to map page number of PgHdr */
@@ -435,6 +436,12 @@ end_ckpt_playback:
 ** Change the maximum number of in-memory pages that are allowed.
 */
 void sqlitepager_set_cachesize(Pager *pPager, int mxPage){
+  if( mxPage>=0 ){
+    pPager->noSync = 0;
+  }else{
+    pPager->noSync = 1;
+    mxPage = -mxPage;
+  }
   if( mxPage>10 ){
     pPager->mxPage = mxPage;
   }
@@ -800,9 +807,8 @@ int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
       /* Recycle an older page.  First locate the page to be recycled.
       ** Try to find one that is not dirty and is near the head of
       ** of the free list */
-      int cnt = pPager->mxPage/2;
       pPg = pPager->pFirst;
-      while( pPg->dirty && 0<cnt-- && pPg->pNextFree ){
+      while( pPg && pPg->dirty ){
         pPg = pPg->pNextFree;
       }
 
@@ -818,7 +824,7 @@ int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
       ** near future.  That is way we write all dirty pages after a
       ** sync.
       */
-      if( pPg==0 || pPg->dirty ){
+      if( pPg==0 ){
         int rc = syncAllPages(pPager);
         if( rc!=0 ){
           sqlitepager_rollback(pPager);
@@ -1081,7 +1087,7 @@ int sqlitepager_write(void *pData){
     }
     assert( pPager->aInJournal!=0 );
     pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
-    pPager->needSync = 1;
+    pPager->needSync = !pPager->noSync;
     pPg->inJournal = 1;
     if( pPager->ckptOpen ){
       pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
@@ -1209,7 +1215,9 @@ int sqlitepager_commit(Pager *pPager){
     rc = sqliteOsWrite(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
     if( rc!=SQLITE_OK ) goto commit_abort;
   }
-  if( sqliteOsSync(&pPager->fd)!=SQLITE_OK ) goto commit_abort;
+  if( !pPager->noSync && sqliteOsSync(&pPager->fd)!=SQLITE_OK ){
+    goto commit_abort;
+  }
   rc = pager_unwritelock(pPager);
   pPager->dbSize = -1;
   return rc;
index 7a2f13b106444905ec0d268f1c0d5937ece62be9..fc521a5f5a39472344d8f553d091fbcfabcfa9e9 100644 (file)
@@ -14,7 +14,7 @@
 ** the parser.  Lemon will also generate a header file containing
 ** numeric codes for all of the tokens.
 **
-** @(#) $Id: parse.y,v 1.55 2002/03/03 23:06:01 drh Exp $
+** @(#) $Id: parse.y,v 1.56 2002/03/05 01:11:14 drh Exp $
 */
 %token_prefix TK_
 %token_type {Token}
@@ -581,7 +581,7 @@ cmd ::= PRAGMA ids(X) EQ ON(Y).          {sqlitePragma(pParse,&X,&Y,0);}
 cmd ::= PRAGMA ids(X) EQ plus_num(Y).    {sqlitePragma(pParse,&X,&Y,0);}
 cmd ::= PRAGMA ids(X) EQ minus_num(Y).   {sqlitePragma(pParse,&X,&Y,1);}
 cmd ::= PRAGMA ids(X) LP ids(Y) RP.      {sqlitePragma(pParse,&X,&Y,0);}
-cmd ::= PRAGMA(Y) ids(X).                {sqlitePragma(pParse,&X,&Y,0);}
+cmd ::= PRAGMA ids(X).                   {sqlitePragma(pParse,&X,&X,0);}
 plus_num(A) ::= plus_opt number(X).   {A = X;}
 minus_num(A) ::= MINUS number(X).     {A = X;}
 number(A) ::= INTEGER(X).  {A = X;}
index 4dd693c325efc342dfb9f60da577dc357599859c..3520a94e93ff80ac3e92433e8b41ace7570337e9 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.101 2002/03/03 23:06:02 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.102 2002/03/05 01:11:14 drh Exp $
 */
 #include "sqlite.h"
 #include "hash.h"
@@ -27,8 +27,8 @@
 ** The maximum number of in-memory pages to use for the main database
 ** table and for temporary tables.
 */
-#define MAX_PAGES   100
-#define TEMP_PAGES   25
+#define MAX_PAGES   2000
+#define TEMP_PAGES   500
 
 /*
 ** Integers of known sizes.  These typedefs might change for architectures
index 1d8989740b74f7087b4483cc265edbef860e4905..f5ab9161cf130ef7dedde705d18d270afb6547ce 100644 (file)
@@ -30,7 +30,7 @@
 ** But other routines are also provided to help in building up
 ** a program instruction by instruction.
 **
-** $Id: vdbe.c,v 1.130 2002/03/03 02:49:51 drh Exp $
+** $Id: vdbe.c,v 1.131 2002/03/05 01:11:14 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -2555,7 +2555,8 @@ case OP_Rollback: {
 **
 ** If P2>0, then read global database parameter number P2.  There is
 ** a small fixed number of global database parameters.  P2==1 is the
-** database version number.  Other parameters are currently unused.
+** database version number.  P2==2 is the recommended pager cache size.
+** Other parameters are currently unused.
 **
 ** There must be a read-lock on the database (either a transaction
 ** must be started or there must be an open cursor) before
@@ -2572,11 +2573,12 @@ case OP_ReadCookie: {
   break;
 }
 
-/* Opcode: SetCookie P1 P2 *
+/* Opcode: SetCookie * P2 *
 **
 ** When P2==0,
 ** this operation changes the value of the schema cookie on the database.
-** The new value is P1.  When P2>0, the value of global database parameter
+** The new value is top of the stack.
+** When P2>0, the value of global database parameter
 ** number P2 is changed.  See ReadCookie for more information about
 ** global database parametes.
 **
@@ -2589,11 +2591,14 @@ case OP_ReadCookie: {
 case OP_SetCookie: {
   int aMeta[SQLITE_N_BTREE_META];
   assert( pOp->p2<SQLITE_N_BTREE_META );
+  VERIFY( if( p->tos<0 ) goto not_enough_stack; )
+  Integerify(p, p->tos)
   rc = sqliteBtreeGetMeta(pBt, aMeta);
   if( rc==SQLITE_OK ){
-    aMeta[1+pOp->p2] = pOp->p1;
+    aMeta[1+pOp->p2] = aStack[p->tos].i;
     rc = sqliteBtreeUpdateMeta(pBt, aMeta);
   }
+  POPSTACK;
   break;
 }
 
diff --git a/tool/speedtest.tcl b/tool/speedtest.tcl
new file mode 100644 (file)
index 0000000..8de4702
--- /dev/null
@@ -0,0 +1,228 @@
+#!/usr/bin/tclsh
+#
+# Run this script using TCLSH to do a speed comparison between
+# various versions of SQLite and PostgreSQL and MySQL
+#
+
+# Run a test
+#
+set cnt 0
+proc runtest {title sqlfile} {
+  global cnt
+  incr cnt
+  puts "<h2>Test $cnt: $title</h2>"
+  set fd [open $sqlfile r]
+  set sql [string trim [read $fd [file size $sqlfile]]]
+  close $fd
+  set sx [split $sql \n]
+  set n [llength $sx]
+  if {$n>8} {
+    set sql {}
+    for {set i 0} {$i<3} {incr i} {append sql [lindex $sx $i]<br>\n}
+    append sql  "<i>... [expr {$n-6}] lines omitted</i><br>\n"
+    for {set i [expr {$n-3}]} {$i<$n} {incr i} {
+      append sql [lindex $sx $i]<br>\n
+    }
+  } else {
+    regsub -all \n [string trim $sql] <br> sql
+  }
+  puts "<blockquote>"
+  puts "$sql"
+  puts "</blockquote><table border=0 cellpadding=0 cellspacing=5>"
+  set format {<tr><td>%s</td><td align="right">%.3f</td></tr>}
+  set t [time "exec psql drh <$sqlfile" 1]
+  set t [expr {[lindex $t 0]/1000000.0}]
+  puts [format $format PostgreSQL: $t]
+  set t [time "exec mysql drh <$sqlfile" 1]
+  set t [expr {[lindex $t 0]/1000000.0}]
+  puts [format $format MySQL: $t]
+#  set t [time "exec ./sqlite232 s232.db <$sqlfile" 1]
+#  set t [expr {[lindex $t 0]/1000000.0}]
+#  puts [format $format {SQLite 2.3.2:} $t]
+#  set t [time "exec ./sqlite-100 s100.db <$sqlfile" 1]
+#  set t [expr {[lindex $t 0]/1000000.0}]
+#  puts [format $format {SQLite 2.4 (cache=100):} $t]
+  set t [time "exec ./sqlite240 s2k.db <$sqlfile" 1]
+  set t [expr {[lindex $t 0]/1000000.0}]
+  puts [format $format {SQLite 2.4 (cache=2000):} $t]
+  set t [time "exec ./sqlite240 sns.db <$sqlfile" 1]
+  set t [expr {[lindex $t 0]/1000000.0}]
+  puts [format $format {SQLite 2.4 (nosync):} $t]
+  puts "</table>"
+}
+
+# Initialize the environment
+#
+expr srand(1)
+catch {exec /bin/sh -c {rm -f s*.db}}
+set fd [open clear.sql w]
+puts $fd {
+  drop table t1;
+  drop table t2;
+}
+close $fd
+catch {exec psql drh <clear.sql}
+catch {exec mysql drh <clear.sql}
+set fd [open 2kinit.sql w]
+puts $fd {PRAGMA cache_size=2000; PRAGMA synchronous=on;}
+close $fd
+exec ./sqlite240 s2k.db <2kinit.sql
+set fd [open nosync-init.sql w]
+puts $fd {PRAGMA cache_size=2000; PRAGMA synchronous=off;}
+close $fd
+exec ./sqlite240 sns.db <nosync-init.sql
+set ones {zero one two three four five six seven eight nine
+          ten eleven twelve thirteen fourteen fifteen sixteen seventeen
+          eighteen nineteen}
+set tens {{} ten twenty thirty forty fifty sixty seventy eighty ninety}
+proc number_name {n} {
+  if {$n>=1000} {
+    set txt "[number_name [expr {$n/1000}]] thousand"
+    set n [expr {$n%1000}]
+  } else {
+    set txt {}
+  }
+  if {$n>100} {
+    append txt " [lindex $::ones [expr {$n/100}]] hundred"
+    set n [expr {$n%100}]
+  }
+  if {$n>19} {
+    append txt " [lindex $::tens [expr {$n/10}]]"
+    set n [expr {$n%10}]
+  }
+  if {$n>0} {
+    append txt " [lindex $::ones $n]"
+  }
+  set txt [string trim $txt]
+  if {$txt==""} {set txt zero}
+  return $txt
+}
+
+# TEST 1
+#
+set fd [open test1.sql w]
+puts $fd "CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100));"
+for {set i 1} {$i<=1000} {incr i} {
+  set r [expr {int(rand()*100000)}]
+  puts $fd "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');"
+}
+close $fd
+runtest {1000 INSERTs} test1.sql
+
+# TEST 2
+#
+set fd [open test2.sql w]
+puts $fd "BEGIN;"
+puts $fd "CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100));"
+for {set i 1} {$i<=25000} {incr i} {
+  set r [expr {int(rand()*500000)}]
+  puts $fd "INSERT INTO t2 VALUES($i,$r,'[number_name $r]');"
+}
+puts $fd "COMMIT;"
+close $fd
+runtest {25000 INSERTs in a transaction} test2.sql
+
+# TEST 3
+#
+set fd [open test3.sql w]
+for {set i 0} {$i<100} {incr i} {
+  set lwr [expr {$i*100}]
+  set upr [expr {($i+10)*100}]
+  puts $fd "SELECT count(*), avg(b) FROM t2 WHERE b>=$lwr AND b<$upr;"
+}
+close $fd
+runtest {100 SELECTs without an index} test3.sql
+
+# TEST 4
+#
+set fd [open test4.sql w]
+puts $fd {CREATE INDEX i2a ON t2(a);}
+puts $fd {CREATE INDEX i2b ON t2(b);}
+close $fd
+runtest {Creating an index} test4.sql
+
+# TEST 5
+#
+set fd [open test5.sql w]
+for {set i 0} {$i<5000} {incr i} {
+  set lwr [expr {$i*100}]
+  set upr [expr {($i+1)*100}]
+  puts $fd "SELECT count(*), avg(b) FROM t2 WHERE b>=$lwr AND b<$upr;"
+}
+close $fd
+runtest {5000 SELECTs with an index} test5.sql
+
+# TEST 6
+#
+set fd [open test6.sql w]
+puts $fd "BEGIN;"
+for {set i 0} {$i<100} {incr i} {
+  set lwr [expr {$i*10}]
+  set upr [expr {($i+1)*10}]
+  puts $fd "UPDATE t1 SET b=b*2 WHERE a>=$lwr AND a<$upr;"
+}
+puts $fd "COMMIT;"
+close $fd
+runtest {100 UPDATEs without an index} test6.sql
+
+
+# TEST 7
+set fd [open test7.sql w]
+puts $fd "BEGIN;"
+for {set i 1} {$i<=25000} {incr i} {
+  puts $fd "UPDATE t2 SET b=b+a WHERE a=$i;"
+}
+puts $fd "COMMIT;"
+close $fd
+runtest {25000 UPDATEs with an index} test7.sql
+
+# TEST 8
+set fd [open test8.sql w]
+puts $fd "BEGIN;"
+puts $fd "INSERT INTO t1 SELECT * FROM t2;"
+puts $fd "INSERT INTO t2 SELECT * FROM t1;"
+puts $fd "COMMIT;"
+close $fd
+runtest {INSERTs from a SELECT} test8.sql
+
+# TEST 9
+#
+set fd [open test9.sql w]
+puts $fd {DELETE FROM t2 WHERE c LIKE '%fifty%';}
+close $fd
+runtest {DELETE without an index} test9.sql
+
+# TEST 10
+#
+set fd [open test10.sql w]
+puts $fd {DELETE FROM t2 WHERE a>10 AND a<20000;}
+close $fd
+runtest {DELETE with an index} test10.sql
+
+# TEST 11
+#
+set fd [open test11.sql w]
+puts $fd {INSERT INTO t2 SELECT * FROM t1;}
+close $fd
+runtest {A big INSERT after a big DELETE} test11.sql
+
+# TEST 12
+#
+set fd [open test12.sql w]
+puts $fd {BEGIN;}
+puts $fd {DELETE FROM t1;}
+for {set i 1} {$i<=1000} {incr i} {
+  set r [expr {int(rand()*100000)}]
+  puts $fd "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');"
+}
+puts $fd {COMMIT;}
+close $fd
+runtest {A big DELETE followed by many small INSERTs} test12.sql
+
+# TEST 13
+#
+set fd [open test13.sql w]
+puts $fd {DROP TABLE t1;}
+puts $fd {DROP TABLE t2;}
+close $fd
+runtest {DROP TABLE} test13.sql
index fe8ac42ce6cb8936dc0094a9792fc46bc5ee5a97..0397ac1241c110ab6f6e708a970e192b5e0f4c2a 100644 (file)
@@ -38,6 +38,8 @@ chng {2002 Mar * (2.4.0)} {
     impact database integrity, since the
     pages contain no real data, but it does make large INSERT operations
     about 2.5 times faster and large DELETEs about 5 times faster.</li>
+<li>Made the CACHE_SIZE pragma persistent</li>
+<li>Added the SYNCHRONOUS pragma</li>
 }
 
 chng {2002 Feb 18 (2.3.3)} {