# 2013 March 20 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl set testprefix mmap1 proc nRead {db} { set bt [btree_from_db $db] db_enter $db array set stats [btree_pager_stats $bt] db_leave $db # puts [array get stats] return $stats(read) } foreach {t mmap_limit nRead c2init} { 1.1 { PRAGMA mmap_limit = 67108864 } 4 {} 1.2 { PRAGMA mmap_limit = 53248 } 150 {} 1.3 { PRAGMA mmap_limit = 0 } 344 {} 1.4 { PRAGMA mmap_limit = 67108864 } 4 {PRAGMA mmap_limit = 67108864 } 1.5 { PRAGMA mmap_limit = 53248 } 150 {PRAGMA mmap_limit = 67108864 } 1.6 { PRAGMA mmap_limit = 0 } 344 {PRAGMA mmap_limit = 67108864 } } { do_multiclient_test tn { sql1 {PRAGMA page_size=1024} sql1 $mmap_limit sql2 $c2init code2 { set ::rcnt 0 proc rblob {n} { set ::rcnt [expr (($::rcnt << 3) + $::rcnt + 456) & 0xFFFFFFFF] set str [format %.8x [expr $::rcnt ^ 0xbdf20da3]] string range [string repeat $str [expr $n/4]] 1 $n } db2 func rblob rblob } sql2 { PRAGMA page_size=1024; PRAGMA auto_vacuum = 1; CREATE TABLE t1(a, b, UNIQUE(a, b)); INSERT INTO t1 VALUES(rblob(500), rblob(500)); INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 2 INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 4 INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 8 INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 16 INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 32 } do_test $t.$tn.1 { sql1 "SELECT count(*) FROM t1; PRAGMA integrity_check ; PRAGMA page_count" } {32 ok 77} # Have connection 2 shrink the file. Check connection 1 can still read it. sql2 { DELETE FROM t1 WHERE rowid%2; } do_test $t.$tn.2 { sql1 "SELECT count(*) FROM t1; PRAGMA integrity_check ; PRAGMA page_count" } {16 ok 42} # Have connection 2 grow the file. Check connection 1 can still read it. sql2 { INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1 } do_test $t.$tn.3 { sql1 "SELECT count(*) FROM t1; PRAGMA integrity_check ; PRAGMA page_count" } {32 ok 79} # Have connection 2 grow the file again. Check connection 1 is still ok. sql2 { INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1 } do_test $t.$tn.4 { sql1 "SELECT count(*) FROM t1; PRAGMA integrity_check ; PRAGMA page_count" } {64 ok 149} # Check that the number of pages read by connection 1 indicates that the # "PRAGMA mmap_limit" command worked. do_test $t.$tn.5 { nRead db } $nRead } } set ::rcnt 0 proc rblob {n} { set ::rcnt [expr (($::rcnt << 3) + $::rcnt + 456) & 0xFFFFFFFF] set str [format %.8x [expr $::rcnt ^ 0xbdf20da3]] string range [string repeat $str [expr $n/4]] 1 $n } reset_db db func rblob rblob do_execsql_test 2.1 { PRAGMA auto_vacuum = 1; PRAGMA mmap_limit = 67108864; PRAGMA journal_mode = wal; CREATE TABLE t1(a, b, UNIQUE(a, b)); INSERT INTO t1 VALUES(rblob(500), rblob(500)); INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 2 INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 4 INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 8 INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 16 INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 32 PRAGMA wal_checkpoint; } {wal 0 103 103} do_execsql_test 2.2 { PRAGMA auto_vacuum; SELECT count(*) FROM t1; } {1 32} do_test 2.3 { sqlite3 db2 test.db db2 func rblob rblob db2 eval { DELETE FROM t1 WHERE (rowid%4); PRAGMA wal_checkpoint; } db2 eval { INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 16 SELECT count(*) FROM t1; } } {16} do_execsql_test 2.4 { PRAGMA wal_checkpoint; } {0 24 24} db2 close reset_db db func rblob rblob do_execsql_test 3.1 { PRAGMA auto_vacuum = 1; CREATE TABLE t1(a, b, UNIQUE(a, b)); INSERT INTO t1 VALUES(rblob(500), rblob(500)); INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 2 INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 4 INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 8 CREATE TABLE t2(a, b, UNIQUE(a, b)); INSERT INTO t2 SELECT * FROM t1; } {} do_test 3.2 { set nRow 0 db eval {SELECT * FROM t2 ORDER BY a, b} { if {$nRow==4} { db eval { DELETE FROM t1 } } incr nRow } set nRow } {8} finish_test