| OLD | NEW |
| 1 # 2013 March 20 | 1 # 2013 March 20 |
| 2 # | 2 # |
| 3 # The author disclaims copyright to this source code. In place of | 3 # The author disclaims copyright to this source code. In place of |
| 4 # a legal notice, here is a blessing: | 4 # a legal notice, here is a blessing: |
| 5 # | 5 # |
| 6 # May you do good and not evil. | 6 # May you do good and not evil. |
| 7 # May you find forgiveness for yourself and forgive others. | 7 # May you find forgiveness for yourself and forgive others. |
| 8 # May you share freely, never taking more than you give. | 8 # May you share freely, never taking more than you give. |
| 9 # | 9 # |
| 10 #*********************************************************************** | 10 #*********************************************************************** |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 proc nRead {db} { | 22 proc nRead {db} { |
| 23 set bt [btree_from_db $db] | 23 set bt [btree_from_db $db] |
| 24 db_enter $db | 24 db_enter $db |
| 25 array set stats [btree_pager_stats $bt] | 25 array set stats [btree_pager_stats $bt] |
| 26 db_leave $db | 26 db_leave $db |
| 27 # puts [array get stats] | 27 # puts [array get stats] |
| 28 return $stats(read) | 28 return $stats(read) |
| 29 } | 29 } |
| 30 | 30 |
| 31 # Return a Tcl script that registers a user-defined scalar function |
| 32 # named rblob() with database handle $dbname. The function returns a |
| 33 # sequence of pseudo-random blobs based on seed value $seed. |
| 34 # |
| 31 proc register_rblob_code {dbname seed} { | 35 proc register_rblob_code {dbname seed} { |
| 32 return [subst -nocommands { | 36 return [subst -nocommands { |
| 33 set ::rcnt $seed | 37 set ::rcnt $seed |
| 34 proc rblob {n} { | 38 proc rblob {n} { |
| 35 set ::rcnt [expr (([set ::rcnt] << 3) + [set ::rcnt] + 456) & 0xFFFFFFFF] | 39 set ::rcnt [expr (([set ::rcnt] << 3) + [set ::rcnt] + 456) & 0xFFFFFFFF] |
| 36 set str [format %.8x [expr [set ::rcnt] ^ 0xbdf20da3]] | 40 set str [format %.8x [expr [set ::rcnt] ^ 0xbdf20da3]] |
| 37 string range [string repeat [set str] [expr [set n]/4]] 1 [set n] | 41 string range [string repeat [set str] [expr [set n]/4]] 1 [set n] |
| 38 } | 42 } |
| 39 $dbname func rblob rblob | 43 $dbname func rblob rblob |
| 40 }] | 44 }] |
| 41 } | 45 } |
| 42 | 46 |
| 47 |
| 43 # For cases 1.1 and 1.4, the number of pages read using xRead() is 4 on | 48 # For cases 1.1 and 1.4, the number of pages read using xRead() is 4 on |
| 44 # unix and 9 on windows. The difference is that windows only ever maps | 49 # unix and 9 on windows. The difference is that windows only ever maps |
| 45 # an integer number of OS pages (i.e. creates mappings that are a multiple | 50 # an integer number of OS pages (i.e. creates mappings that are a multiple |
| 46 # of 4KB in size). Whereas on unix any sized mapping may be created. | 51 # of 4KB in size). Whereas on unix any sized mapping may be created. |
| 47 # | 52 # |
| 48 foreach {t mmap_size nRead c2init} { | 53 foreach {t mmap_size nRead c2init} { |
| 49 1.1 { PRAGMA mmap_size = 67108864 } /[49]/ {PRAGMA mmap_size = 0} | 54 1.1 { PRAGMA mmap_size = 67108864 } /[49]/ {PRAGMA mmap_size = 0} |
| 50 1.2 { PRAGMA mmap_size = 53248 } 150 {PRAGMA mmap_size = 0} | 55 1.2 { PRAGMA mmap_size = 53248 } 150 {PRAGMA mmap_size = 0} |
| 51 1.3 { PRAGMA mmap_size = 0 } 344 {PRAGMA mmap_size = 0} | 56 1.3 { PRAGMA mmap_size = 0 } 344 {PRAGMA mmap_size = 0} |
| 52 1.4 { PRAGMA mmap_size = 67108864 } /[49]/ {PRAGMA mmap_size = 67108864 } | 57 1.4 { PRAGMA mmap_size = 67108864 } /[49]/ {PRAGMA mmap_size = 67108864 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 76 INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 32 | 81 INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 32 |
| 77 } | 82 } |
| 78 do_test $t.$tn.1 { | 83 do_test $t.$tn.1 { |
| 79 sql1 "SELECT count(*) FROM t1; PRAGMA integrity_check ; PRAGMA page_count" | 84 sql1 "SELECT count(*) FROM t1; PRAGMA integrity_check ; PRAGMA page_count" |
| 80 } {32 ok 77} | 85 } {32 ok 77} |
| 81 | 86 |
| 82 # Have connection 2 shrink the file. Check connection 1 can still read it. | 87 # Have connection 2 shrink the file. Check connection 1 can still read it. |
| 83 sql2 { DELETE FROM t1 WHERE rowid%2; } | 88 sql2 { DELETE FROM t1 WHERE rowid%2; } |
| 84 do_test $t.$tn.2 { | 89 do_test $t.$tn.2 { |
| 85 sql1 "SELECT count(*) FROM t1; PRAGMA integrity_check ; PRAGMA page_count" | 90 sql1 "SELECT count(*) FROM t1; PRAGMA integrity_check ; PRAGMA page_count" |
| 86 } {16 ok 42} | 91 } "16 ok [expr {42+[nonzero_reserved_bytes]}]" |
| 87 | 92 |
| 88 # Have connection 2 grow the file. Check connection 1 can still read it. | 93 # Have connection 2 grow the file. Check connection 1 can still read it. |
| 89 sql2 { INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1 } | 94 sql2 { INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1 } |
| 90 do_test $t.$tn.3 { | 95 do_test $t.$tn.3 { |
| 91 sql1 "SELECT count(*) FROM t1; PRAGMA integrity_check ; PRAGMA page_count" | 96 sql1 "SELECT count(*) FROM t1; PRAGMA integrity_check ; PRAGMA page_count" |
| 92 } {32 ok 79} | 97 } {32 ok 79} |
| 93 | 98 |
| 94 # Have connection 2 grow the file again. Check connection 1 is still ok. | 99 # Have connection 2 grow the file again. Check connection 1 is still ok. |
| 95 sql2 { INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1 } | 100 sql2 { INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1 } |
| 96 do_test $t.$tn.4 { | 101 do_test $t.$tn.4 { |
| 97 sql1 "SELECT count(*) FROM t1; PRAGMA integrity_check ; PRAGMA page_count" | 102 sql1 "SELECT count(*) FROM t1; PRAGMA integrity_check ; PRAGMA page_count" |
| 98 } {64 ok 149} | 103 } {64 ok 149} |
| 99 | 104 |
| 100 # Check that the number of pages read by connection 1 indicates that the | 105 # Check that the number of pages read by connection 1 indicates that the |
| 101 # "PRAGMA mmap_size" command worked. | 106 # "PRAGMA mmap_size" command worked. |
| 102 do_test $t.$tn.5 { nRead db } $nRead | 107 if {[nonzero_reserved_bytes]==0} { |
| 108 do_test $t.$tn.5 { nRead db } $nRead |
| 109 } |
| 103 } | 110 } |
| 104 } | 111 } |
| 105 | 112 |
| 106 set ::rcnt 0 | 113 set ::rcnt 0 |
| 107 proc rblob {n} { | 114 proc rblob {n} { |
| 108 set ::rcnt [expr (($::rcnt << 3) + $::rcnt + 456) & 0xFFFFFFFF] | 115 set ::rcnt [expr (($::rcnt << 3) + $::rcnt + 456) & 0xFFFFFFFF] |
| 109 set str [format %.8x [expr $::rcnt ^ 0xbdf20da3]] | 116 set str [format %.8x [expr $::rcnt ^ 0xbdf20da3]] |
| 110 string range [string repeat $str [expr $n/4]] 1 $n | 117 string range [string repeat $str [expr $n/4]] 1 $n |
| 111 } | 118 } |
| 112 | 119 |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 | 269 |
| 263 do_test 5.4 { | 270 do_test 5.4 { |
| 264 sqlite3_step $::STMT | 271 sqlite3_step $::STMT |
| 265 sqlite3_column_text $::STMT 0 | 272 sqlite3_column_text $::STMT 0 |
| 266 } $bbb | 273 } $bbb |
| 267 | 274 |
| 268 do_test 5.5 { | 275 do_test 5.5 { |
| 269 sqlite3_finalize $::STMT | 276 sqlite3_finalize $::STMT |
| 270 } SQLITE_OK | 277 } SQLITE_OK |
| 271 | 278 |
| 272 #------------------------------------------------------------------------- | |
| 273 # Test various mmap_size settings. | |
| 274 # | |
| 275 foreach {tn1 mmap1 mmap2} { | |
| 276 1 6144 167773 | |
| 277 2 18432 140399 | |
| 278 3 43008 401302 | |
| 279 4 92160 253899 | |
| 280 5 190464 2 | |
| 281 6 387072 752431 | |
| 282 7 780288 291143 | |
| 283 8 1566720 594306 | |
| 284 9 3139584 829137 | |
| 285 10 6285312 793963 | |
| 286 11 12576768 1015590 | |
| 287 } { | |
| 288 do_multiclient_test tn { | |
| 289 sql1 { | |
| 290 CREATE TABLE t1(a PRIMARY KEY); | |
| 291 CREATE TABLE t2(x); | |
| 292 INSERT INTO t2 VALUES(''); | |
| 293 } | |
| 294 | |
| 295 code1 [register_rblob_code db 0] | |
| 296 code2 [register_rblob_code db2 444] | |
| 297 | |
| 298 sql1 "PRAGMA mmap_size = $mmap1" | |
| 299 sql2 "PRAGMA mmap_size = $mmap2" | |
| 300 | |
| 301 do_test $tn1.$tn { | |
| 302 for {set i 1} {$i <= 100} {incr i} { | |
| 303 if {$i % 2} { | |
| 304 set c1 sql1 | |
| 305 set c2 sql2 | |
| 306 } else { | |
| 307 set c1 sql2 | |
| 308 set c2 sql1 | |
| 309 } | |
| 310 | |
| 311 $c1 { | |
| 312 INSERT INTO t1 VALUES( rblob(5000) ); | |
| 313 UPDATE t2 SET x = (SELECT md5sum(a) FROM t1); | |
| 314 } | |
| 315 | |
| 316 set res [$c2 { | |
| 317 SELECT count(*) FROM t1; | |
| 318 SELECT x == (SELECT md5sum(a) FROM t1) FROM t2; | |
| 319 PRAGMA integrity_check; | |
| 320 }] | |
| 321 if {$res != [list $i 1 ok]} { | |
| 322 do_test $tn1.$tn.$i { | |
| 323 set ::res | |
| 324 } [list $i 1 ok] | |
| 325 } | |
| 326 } | |
| 327 set res 1 | |
| 328 } {1} | |
| 329 } | |
| 330 } | |
| 331 | |
| 332 | 279 |
| 333 finish_test | 280 finish_test |
| OLD | NEW |