1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Add the ability to turn of calls to fsync() using the "synchronous" pragma.

Increased the default cache size from 100 to 2000 and made the "cache_size"
pragma persistent. (CVS 418)

FossilOrigin-Name: 414da4af1f4aebc3936ca339fbc7932add081912
This commit is contained in:
drh
2002-03-05 01:11:12 +00:00
parent ef2daf547d
commit 603240cf5d
11 changed files with 395 additions and 63 deletions

View File

@@ -1,5 +1,5 @@
C Updates\sto\sthe\sdocumentation.\s\sChanged\sversion\snumber\sto\s2.4.0-beta1\s(CVS\s417) 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-04T02:26:16 D 2002-03-05T01:11:13
F Makefile.in 50f1b3351df109b5774771350d8c1b8d3640130d F Makefile.in 50f1b3351df109b5774771350d8c1b8d3640130d
F Makefile.template 89e373b2dad0321df00400fa968dc14b61a03296 F Makefile.template 89e373b2dad0321df00400fa968dc14b61a03296
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0 F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
@@ -21,27 +21,27 @@ F sqlite.1 2e2bb0529ef468ade9e4322bd609d0695fb9ded9
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6 F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
F src/btree.c d25ea795a0f7017bc2099c437e6cc01d4c31b22d F src/btree.c d25ea795a0f7017bc2099c437e6cc01d4c31b22d
F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3 F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3
F src/build.c e11b0daa79ba894c7476c33372b1dc42b13471e6 F src/build.c 0f3c6b6482e0b74284b22661de1b813a0bfb0197
F src/delete.c 577da499162291c1855f0b304b211bffcf9da945 F src/delete.c 577da499162291c1855f0b304b211bffcf9da945
F src/expr.c e12ca550536c0bae7a3acef49dfa3068fe5f0900 F src/expr.c e12ca550536c0bae7a3acef49dfa3068fe5f0900
F src/func.c 87516e7dc37190c24af77593931a5d09d797520a F src/func.c 87516e7dc37190c24af77593931a5d09d797520a
F src/hash.c cc259475e358baaf299b00a2c7370f2b03dda892 F src/hash.c cc259475e358baaf299b00a2c7370f2b03dda892
F src/hash.h dca065dda89d4575f3176e75e9a3dc0f4b4fb8b9 F src/hash.h dca065dda89d4575f3176e75e9a3dc0f4b4fb8b9
F src/insert.c 42bfd145efd428d7e5f200dd49ea0b816fc30d79 F src/insert.c 42bfd145efd428d7e5f200dd49ea0b816fc30d79
F src/main.c 5651146585ae613e759fcf372ee064e4940c2463 F src/main.c 3015c23faeff1709b1528f07c0bfe839284090a8
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
F src/os.c f6bc9b7ab530346bb7fef2ed39f2f1f214bc14ea F src/os.c db969ecd1bcb4fef01b0b541b8b17401b0eb7ed2
F src/os.h a17596ecc7f38a228b83ecdb661fb03ce44726d6 F src/os.h a17596ecc7f38a228b83ecdb661fb03ce44726d6
F src/pager.c 0aa358a378c416ee0b0be5bf03fa7c35f7992c9b F src/pager.c 41af87908cd76a50d7e22cf3c7a4d479e3c9a512
F src/pager.h feb18aab2f6dea439393f23a382699b9b1053c32 F src/pager.h feb18aab2f6dea439393f23a382699b9b1053c32
F src/parse.y 25b794bfbed2a68d13d7d40a986a0ebe2beb3e24 F src/parse.y f7483ccff7b8f16d3655df59775d85b62b06897e
F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
F src/select.c 49c78aa0c96dda036846937b516658536db98b56 F src/select.c 49c78aa0c96dda036846937b516658536db98b56
F src/shell.c b3454229599246b944cdb5b95753af3fca5d8bb0 F src/shell.c b3454229599246b944cdb5b95753af3fca5d8bb0
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
F src/sqlite.h.in a9b5772604265f98f3120573ef29e37b9d917216 F src/sqlite.h.in a9b5772604265f98f3120573ef29e37b9d917216
F src/sqliteInt.h dde4e52e234e54e8ac9d3a1964e93c5fa6c2de15 F src/sqliteInt.h 46f41e2f4cf90cdbe002f6b4143ae3f16ae0b872
F src/table.c 203a09d5d0009eeeb1f670370d52b4ce163a3b52 F src/table.c 203a09d5d0009eeeb1f670370d52b4ce163a3b52
F src/tclsqlite.c b9cf346e95291cb4c4f1bf5ac1d77db6b8ad023d F src/tclsqlite.c b9cf346e95291cb4c4f1bf5ac1d77db6b8ad023d
F src/test1.c 33efd350dca27c52c58c553c04fd3a6a51f13c1f F src/test1.c 33efd350dca27c52c58c553c04fd3a6a51f13c1f
@@ -51,7 +51,7 @@ F src/threadtest.c 81f0598e0f031c1bd506af337fdc1b7e8dff263f
F src/tokenize.c 4b5d30590a744b9bb5605a92d1f620ab2e7e75af F src/tokenize.c 4b5d30590a744b9bb5605a92d1f620ab2e7e75af
F src/update.c 7dd714a6a7fa47f849ebb36b6d915974d6c6accb F src/update.c 7dd714a6a7fa47f849ebb36b6d915974d6c6accb
F src/util.c 00a35b421c92ae0d7cfa51bd87f7d4995f464d19 F src/util.c 00a35b421c92ae0d7cfa51bd87f7d4995f464d19
F src/vdbe.c 4989cd3e6f4f699c9b08cd1980d1b588cede5c1f F src/vdbe.c 0b634bbe3d1a770136b9f7324804bb55903a9b17
F src/vdbe.h f9be1f6e9a336c3ff4d14ea7489ee976e07460cc F src/vdbe.h f9be1f6e9a336c3ff4d14ea7489ee976e07460cc
F src/where.c 34d91fd5d822c2663caeb023f72d60df316ebf29 F src/where.c 34d91fd5d822c2663caeb023f72d60df316ebf29
F test/all.test 7a8a8a7a579ed2bb4d8976d55402f21eacd58049 F test/all.test 7a8a8a7a579ed2bb4d8976d55402f21eacd58049
@@ -108,11 +108,12 @@ F tool/opNames.awk 5ba1f48aa854ee3b7c3d2b54233665bc3e649ea2
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/renumberOps.awk 6d067177ad5f8d711b79577b462da9b3634bd0a9 F tool/renumberOps.awk 6d067177ad5f8d711b79577b462da9b3634bd0a9
F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816 F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816
F tool/speedtest.tcl 31a2f06e3d2153f4311b13cd6fd5e19b7adc8373
F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4 F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
F www/arch.tcl 72a0c80e9054cc7025a50928d28d9c75c02c2b8b F www/arch.tcl 72a0c80e9054cc7025a50928d28d9c75c02c2b8b
F www/c_interface.tcl 567cda531aac9d68a61ef02e26c6b202bd856db2 F www/c_interface.tcl 567cda531aac9d68a61ef02e26c6b202bd856db2
F www/changes.tcl cdd351b0f358bc23ca6243f3ca52c35ca1bede26 F www/changes.tcl b43d9e32ed7af9a93c5a9b7321abe2ee6a8f4ea9
F www/conflict.tcl 81dd21f9a679e60aae049e9dd8ab53d59570cda2 F www/conflict.tcl 81dd21f9a679e60aae049e9dd8ab53d59570cda2
F www/crosscompile.tcl 3622ebbe518927a3854a12de51344673eb2dd060 F www/crosscompile.tcl 3622ebbe518927a3854a12de51344673eb2dd060
F www/download.tcl a6d75b8b117cd33dcb090bef7e80d7556d28ebe0 F www/download.tcl a6d75b8b117cd33dcb090bef7e80d7556d28ebe0
@@ -127,7 +128,7 @@ F www/speed.tcl 83457b2bf6bb430900bd48ca3dd98264d9a916a5
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279 F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49 F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
P 813077623087ffc6cd506f57cf6d1e3d9239f806 P 36a8fe0ad0ee2a67afafc04125dcc085ec1b5a13
R fe676fb38cbe5a2068c89e56308a155d R e93330a0aa7a7fa6a56e7a5c31b63757
U drh U drh
Z 9a81a81e1e363e5bb6c841e14ddef308 Z b84940384f009522e2520b7d71139ff4

View File

@@ -1 +1 @@
36a8fe0ad0ee2a67afafc04125dcc085ec1b5a13 414da4af1f4aebc3936ca339fbc7932add081912

View File

@@ -25,7 +25,7 @@
** ROLLBACK ** ROLLBACK
** PRAGMA ** 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 "sqliteInt.h"
#include <ctype.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 ){ if( !pParse->initFlag && (v = sqliteGetVdbe(pParse))!=0 ){
sqliteBeginWriteOperation(pParse); sqliteBeginWriteOperation(pParse);
if( !isTemp ){ 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); sqliteVdbeAddOp(v, OP_OpenWrite, 0, 2);
sqliteVdbeChangeP3(v, -1, MASTER_NAME, P3_STATIC); sqliteVdbeChangeP3(v, -1, MASTER_NAME, P3_STATIC);
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0); 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_MakeRecord, 5, 0);
sqliteVdbeAddOp(v, OP_PutIntKey, 0, 0); sqliteVdbeAddOp(v, OP_PutIntKey, 0, 0);
changeCookie(db); 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); sqliteVdbeAddOp(v, OP_Close, 0, 0);
} }
if( pSelect ){ if( pSelect ){
@@ -1023,7 +1025,8 @@ void sqliteDropTable(Parse *pParse, Token *pName, int isView){
{ OP_Ne, 0, ADDR(8), 0}, { OP_Ne, 0, ADDR(8), 0},
{ OP_Delete, 0, 0, 0}, { OP_Delete, 0, 0, 0},
{ OP_Next, 0, ADDR(4), 0}, /* 8 */ { 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}, { OP_Close, 0, 0, 0},
}; };
Index *pIdx; Index *pIdx;
@@ -1337,7 +1340,8 @@ void sqliteCreateIndex(
if( pTable!=0 ){ if( pTable!=0 ){
if( !isTemp ){ if( !isTemp ){
changeCookie(db); 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); sqliteVdbeAddOp(v, OP_Close, 0, 0);
} }
sqliteEndWriteOperation(pParse); sqliteEndWriteOperation(pParse);
@@ -1387,7 +1391,8 @@ void sqliteDropIndex(Parse *pParse, Token *pName){
{ OP_Next, 0, ADDR(4), 0}, { OP_Next, 0, ADDR(4), 0},
{ OP_Goto, 0, ADDR(10),0}, { OP_Goto, 0, ADDR(10),0},
{ OP_Delete, 0, 0, 0}, /* 9 */ { 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}, { OP_Close, 0, 0, 0},
}; };
int base; int base;
@@ -1732,8 +1737,58 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
} }
if( sqliteStrICmp(zLeft,"cache_size")==0 ){ if( sqliteStrICmp(zLeft,"cache_size")==0 ){
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); int size = atoi(zRight);
sqliteBtreeSetCacheSize(db->pBe, size); 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 }else
if( sqliteStrICmp(zLeft, "vdbe_trace")==0 ){ if( sqliteStrICmp(zLeft, "vdbe_trace")==0 ){

View File

@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be ** other files are for internal use by SQLite and should not be
** accessed by users of the library. ** 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 "sqliteInt.h"
#include "os.h" #include "os.h"
@@ -42,6 +42,13 @@ static int sqliteOpenCb(void *pDb, int argc, char **argv, char **azColName){
assert( argc==4 ); assert( argc==4 );
switch( argv[0][0] ){ 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 */ case 'f': { /* File format */
db->file_format = atoi(argv[3]); db->file_format = atoi(argv[3]);
break; break;
@@ -176,6 +183,14 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){
{ OP_ReadCookie, 0, 1, 0}, { OP_ReadCookie, 0, 1, 0},
{ OP_Callback, 4, 0, 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 /* Send the initial schema cookie to the callback
*/ */
{ OP_String, 0, 0, "schema_cookie"}, { OP_String, 0, 0, "schema_cookie"},
@@ -192,45 +207,45 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){
*/ */
{ OP_ReadCookie, 0, 1, 0}, { OP_ReadCookie, 0, 1, 0},
{ OP_Integer, 2, 0, 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 /* This is the code for doing a single scan through the SQLITE_MASTER
** table. This code runs for format 2 and greater. ** table. This code runs for format 2 and greater.
*/ */
{ OP_Rewind, 0, 21, 0}, { OP_Rewind, 0, 26, 0},
{ OP_Column, 0, 0, 0}, /* 15 */ { OP_Column, 0, 0, 0}, /* 20 */
{ OP_Column, 0, 1, 0}, { OP_Column, 0, 1, 0},
{ OP_Column, 0, 3, 0}, { OP_Column, 0, 3, 0},
{ OP_Column, 0, 4, 0}, { OP_Column, 0, 4, 0},
{ OP_Callback, 4, 0, 0}, { OP_Callback, 4, 0, 0},
{ OP_Next, 0, 15, 0}, { OP_Next, 0, 20, 0},
{ OP_Close, 0, 0, 0}, /* 21 */ { OP_Close, 0, 0, 0}, /* 26 */
{ OP_Halt, 0, 0, 0}, { OP_Halt, 0, 0, 0},
/* This is the code for doing two passes through SQLITE_MASTER. This /* This is the code for doing two passes through SQLITE_MASTER. This
** code runs for file format 1. ** code runs for file format 1.
*/ */
{ OP_Rewind, 0, 43, 0}, /* 23 */ { OP_Rewind, 0, 48, 0}, /* 28 */
{ OP_Column, 0, 0, 0}, /* 24 */ { OP_Column, 0, 0, 0}, /* 29 */
{ OP_String, 0, 0, "table"}, { OP_String, 0, 0, "table"},
{ OP_Ne, 0, 32, 0}, { OP_Ne, 0, 37, 0},
{ OP_Column, 0, 0, 0}, { OP_Column, 0, 0, 0},
{ OP_Column, 0, 1, 0}, { OP_Column, 0, 1, 0},
{ OP_Column, 0, 3, 0}, { OP_Column, 0, 3, 0},
{ OP_Column, 0, 4, 0}, { OP_Column, 0, 4, 0},
{ OP_Callback, 4, 0, 0}, { OP_Callback, 4, 0, 0},
{ OP_Next, 0, 24, 0}, /* 32 */ { OP_Next, 0, 29, 0}, /* 37 */
{ OP_Rewind, 0, 43, 0}, /* 33 */ { OP_Rewind, 0, 48, 0}, /* 38 */
{ OP_Column, 0, 0, 0}, /* 34 */ { OP_Column, 0, 0, 0}, /* 39 */
{ OP_String, 0, 0, "index"}, { OP_String, 0, 0, "index"},
{ OP_Ne, 0, 42, 0}, { OP_Ne, 0, 47, 0},
{ OP_Column, 0, 0, 0}, { OP_Column, 0, 0, 0},
{ OP_Column, 0, 1, 0}, { OP_Column, 0, 1, 0},
{ OP_Column, 0, 3, 0}, { OP_Column, 0, 3, 0},
{ OP_Column, 0, 4, 0}, { OP_Column, 0, 4, 0},
{ OP_Callback, 4, 0, 0}, { OP_Callback, 4, 0, 0},
{ OP_Next, 0, 34, 0}, /* 42 */ { OP_Next, 0, 39, 0}, /* 47 */
{ OP_Close, 0, 0, 0}, /* 43 */ { OP_Close, 0, 0, 0}, /* 48 */
{ OP_Halt, 0, 0, 0}, { OP_Halt, 0, 0, 0},
}; };

View File

@@ -43,6 +43,20 @@
# include <winbase.h> # include <winbase.h>
#endif #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 #if OS_UNIX
/* /*
@@ -477,6 +491,7 @@ int sqliteOsRead(OsFile *id, void *pBuf, int amt){
#if OS_UNIX #if OS_UNIX
int got; int got;
SimulateIOError(SQLITE_IOERR); SimulateIOError(SQLITE_IOERR);
TRACE2("READ %d\n", last_page);
got = read(id->fd, pBuf, amt); got = read(id->fd, pBuf, amt);
if( got<0 ) got = 0; if( got<0 ) got = 0;
return got==amt ? SQLITE_OK : SQLITE_IOERR; return got==amt ? SQLITE_OK : SQLITE_IOERR;
@@ -499,6 +514,7 @@ int sqliteOsWrite(OsFile *id, const void *pBuf, int amt){
#if OS_UNIX #if OS_UNIX
int wrote; int wrote;
SimulateIOError(SQLITE_IOERR); SimulateIOError(SQLITE_IOERR);
TRACE2("WRITE %d\n", last_page);
wrote = write(id->fd, pBuf, amt); wrote = write(id->fd, pBuf, amt);
if( wrote<amt ) return SQLITE_FULL; if( wrote<amt ) return SQLITE_FULL;
return SQLITE_OK; return SQLITE_OK;
@@ -517,6 +533,7 @@ int sqliteOsWrite(OsFile *id, const void *pBuf, int amt){
** Move the read/write pointer in a file. ** Move the read/write pointer in a file.
*/ */
int sqliteOsSeek(OsFile *id, int offset){ int sqliteOsSeek(OsFile *id, int offset){
SEEK(offset/1024 + 1);
#if OS_UNIX #if OS_UNIX
lseek(id->fd, offset, SEEK_SET); lseek(id->fd, offset, SEEK_SET);
return SQLITE_OK; return SQLITE_OK;
@@ -532,6 +549,7 @@ int sqliteOsSeek(OsFile *id, int offset){
*/ */
int sqliteOsSync(OsFile *id){ int sqliteOsSync(OsFile *id){
SimulateIOError(SQLITE_IOERR); SimulateIOError(SQLITE_IOERR);
TRACE1("SYNC\n");
#if OS_UNIX #if OS_UNIX
return fsync(id->fd)==0 ? SQLITE_OK : SQLITE_IOERR; return fsync(id->fd)==0 ? SQLITE_OK : SQLITE_IOERR;
#endif #endif

View File

@@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while ** file simultaneously, or one process from reading the database while
** another is writing. ** 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 "sqliteInt.h"
#include "pager.h" #include "pager.h"
@@ -93,7 +93,7 @@ struct PgHdr {
** How big to make the hash table used for locating in-memory pages ** How big to make the hash table used for locating in-memory pages
** by page number. Knuth says this should be a prime number. ** 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. ** A open page cache is an instance of the following structure.
@@ -103,8 +103,6 @@ struct Pager {
char *zJournal; /* Name of the journal file */ char *zJournal; /* Name of the journal file */
OsFile fd, jfd; /* File descriptors for database and journal */ OsFile fd, jfd; /* File descriptors for database and journal */
OsFile cpfd; /* File descriptor for the checkpoint 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 dbSize; /* Number of pages in the file */
int origDbSize; /* dbSize before the current change */ int origDbSize; /* dbSize before the current change */
int ckptSize, ckptJSize; /* Size of database and journal at ckpt_begin() */ 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 nRef; /* Number of in-memory pages with PgHdr.nRef>0 */
int mxPage; /* Maximum number of pages to hold in cache */ int mxPage; /* Maximum number of pages to hold in cache */
int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */ int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */
unsigned char state; /* SQLITE_UNLOCK, _READLOCK or _WRITELOCK */ u8 journalOpen; /* True if journal file descriptors is valid */
unsigned char errMask; /* One of several kinds of errors */ u8 ckptOpen; /* True if the checkpoint journal is open */
unsigned char tempFile; /* zFilename is a temporary file */ u8 noSync; /* Do not sync the journal if true */
unsigned char readOnly; /* True for a read-only database */ u8 state; /* SQLITE_UNLOCK, _READLOCK or _WRITELOCK */
unsigned char needSync; /* True if an fsync() is needed on the journal */ u8 errMask; /* One of several kinds of errors */
unsigned char *aInJournal; /* One bit for each page in the database file */ u8 tempFile; /* zFilename is a temporary file */
unsigned char *aInCkpt; /* One bit for each page in the database */ 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 *pFirst, *pLast; /* List of free pages */
PgHdr *pAll; /* List of all pages */ PgHdr *pAll; /* List of all pages */
PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number of PgHdr */ 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. ** Change the maximum number of in-memory pages that are allowed.
*/ */
void sqlitepager_set_cachesize(Pager *pPager, int mxPage){ void sqlitepager_set_cachesize(Pager *pPager, int mxPage){
if( mxPage>=0 ){
pPager->noSync = 0;
}else{
pPager->noSync = 1;
mxPage = -mxPage;
}
if( mxPage>10 ){ if( mxPage>10 ){
pPager->mxPage = mxPage; 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. /* 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 ** Try to find one that is not dirty and is near the head of
** of the free list */ ** of the free list */
int cnt = pPager->mxPage/2;
pPg = pPager->pFirst; pPg = pPager->pFirst;
while( pPg->dirty && 0<cnt-- && pPg->pNextFree ){ while( pPg && pPg->dirty ){
pPg = pPg->pNextFree; 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 ** near future. That is way we write all dirty pages after a
** sync. ** sync.
*/ */
if( pPg==0 || pPg->dirty ){ if( pPg==0 ){
int rc = syncAllPages(pPager); int rc = syncAllPages(pPager);
if( rc!=0 ){ if( rc!=0 ){
sqlitepager_rollback(pPager); sqlitepager_rollback(pPager);
@@ -1081,7 +1087,7 @@ int sqlitepager_write(void *pData){
} }
assert( pPager->aInJournal!=0 ); assert( pPager->aInJournal!=0 );
pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7); pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
pPager->needSync = 1; pPager->needSync = !pPager->noSync;
pPg->inJournal = 1; pPg->inJournal = 1;
if( pPager->ckptOpen ){ if( pPager->ckptOpen ){
pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7); 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); rc = sqliteOsWrite(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
if( rc!=SQLITE_OK ) goto commit_abort; 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); rc = pager_unwritelock(pPager);
pPager->dbSize = -1; pPager->dbSize = -1;
return rc; return rc;

View File

@@ -14,7 +14,7 @@
** the parser. Lemon will also generate a header file containing ** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens. ** 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_prefix TK_
%token_type {Token} %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 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) EQ minus_num(Y). {sqlitePragma(pParse,&X,&Y,1);}
cmd ::= PRAGMA ids(X) LP ids(Y) RP. {sqlitePragma(pParse,&X,&Y,0);} 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;} plus_num(A) ::= plus_opt number(X). {A = X;}
minus_num(A) ::= MINUS number(X). {A = X;} minus_num(A) ::= MINUS number(X). {A = X;}
number(A) ::= INTEGER(X). {A = X;} number(A) ::= INTEGER(X). {A = X;}

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** 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 "sqlite.h"
#include "hash.h" #include "hash.h"
@@ -27,8 +27,8 @@
** The maximum number of in-memory pages to use for the main database ** The maximum number of in-memory pages to use for the main database
** table and for temporary tables. ** table and for temporary tables.
*/ */
#define MAX_PAGES 100 #define MAX_PAGES 2000
#define TEMP_PAGES 25 #define TEMP_PAGES 500
/* /*
** Integers of known sizes. These typedefs might change for architectures ** Integers of known sizes. These typedefs might change for architectures

View File

@@ -30,7 +30,7 @@
** But other routines are also provided to help in building up ** But other routines are also provided to help in building up
** a program instruction by instruction. ** 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 "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -2555,7 +2555,8 @@ case OP_Rollback: {
** **
** If P2>0, then read global database parameter number P2. There is ** If P2>0, then read global database parameter number P2. There is
** a small fixed number of global database parameters. P2==1 is the ** 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 ** There must be a read-lock on the database (either a transaction
** must be started or there must be an open cursor) before ** must be started or there must be an open cursor) before
@@ -2572,11 +2573,12 @@ case OP_ReadCookie: {
break; break;
} }
/* Opcode: SetCookie P1 P2 * /* Opcode: SetCookie * P2 *
** **
** When P2==0, ** When P2==0,
** this operation changes the value of the schema cookie on the database. ** 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 ** number P2 is changed. See ReadCookie for more information about
** global database parametes. ** global database parametes.
** **
@@ -2589,11 +2591,14 @@ case OP_ReadCookie: {
case OP_SetCookie: { case OP_SetCookie: {
int aMeta[SQLITE_N_BTREE_META]; int aMeta[SQLITE_N_BTREE_META];
assert( pOp->p2<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); rc = sqliteBtreeGetMeta(pBt, aMeta);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
aMeta[1+pOp->p2] = pOp->p1; aMeta[1+pOp->p2] = aStack[p->tos].i;
rc = sqliteBtreeUpdateMeta(pBt, aMeta); rc = sqliteBtreeUpdateMeta(pBt, aMeta);
} }
POPSTACK;
break; break;
} }

228
tool/speedtest.tcl Normal file
View File

@@ -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

View File

@@ -38,6 +38,8 @@ chng {2002 Mar * (2.4.0)} {
impact database integrity, since the impact database integrity, since the
pages contain no real data, but it does make large INSERT operations 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> 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)} { chng {2002 Feb 18 (2.3.3)} {