-C Add\stest\sfile\ssort4.test,\scontaining\sbrute\sforce\stests\sfor\sthe\smulti-theaded\ssorter.
-D 2014-05-05T20:03:50.967
+C Re-implement\sthe\score\sof\sthe\smulti-threaded\ssorter\stests\sin\ssort4.test\susing\sC.\sRun\seach\stest\sin\ssort4.test\sten\stimes,\sor\srepeat\sall\stests\sfor\s300\sseconds\sas\spart\sof\sthe\s"multithread"\spermutation\stest.
+D 2014-05-06T15:38:07.762
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in ad0921c4b2780d01868cf69b419a4f102308d125
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c e87c99e28a145943666b51b212dacae35fcea0bd
-F src/test1.c bd88cc00bff2f15279d808e84501f06148c144f9
+F src/test1.c a0e59104fec5626bb1d1bd746157f43e85245e4b
F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54
-F test/permutations.test 465bc22a873ced74a6d1dedc0dde5da424be6e6a
+F test/permutations.test 33e7e239ba494fdb30e2f4ffc64c508b145ff42f
F test/pragma.test adb21a90875bc54a880fa939c4d7c46598905aa0
F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
F test/sort.test 688468cef8c9a66fcc1d54235de8e4deac745690
F test/sort2.test c5e25eb674689e291d06b5209fe8d337ae0ec010
F test/sort3.test 6178ade30810ac9166fcdf14b7065e49c0f534e2
-F test/sort4.test a29761a7d05f194e516e91a03d38f8194ac9849d
+F test/sort4.test 5cce4601abc9b1b63ac25d087723b257710577bb
F test/sortfault.test 1a12b6e27d475f50658a8164aaa34f0080a86b36
F test/speed1.test f2974a91d79f58507ada01864c0e323093065452
F test/speed1p.explain d841e650a04728b39e6740296b852dccdca9b2cb
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 2d2edfe58db101d42a96772b856e6e55b401aab6
-R a3f7784643670968322db5c49315411c
+P 9cc364c42cc64ab7b55b5c55e303fb63a456cf00
+R 3ed4f872bc36ee2cfbd000cc3f4dde43
U dan
-Z cca87b3c456f151b38b423a6310da351
+Z 5684026d864e64d9d77cb71d6b4cd16b
-9cc364c42cc64ab7b55b5c55e303fb63a456cf00
\ No newline at end of file
+208b2b04d4d282bec4424ea7160a123ba549d118
\ No newline at end of file
return TCL_OK;
}
+/*
+** sorter_test_sort4_helper DB SQL1 NSTEP SQL2
+**
+** Compile SQL statement $SQL1 and step it $NSTEP times. For each row,
+** check that the leftmost and rightmost columns returned are both integers,
+** and that both contain the same value.
+**
+** Then execute statement $SQL2. Check that the statement returns the same
+** set of integers in the same order as in the previous step (using $SQL1).
+*/
+static int sorter_test_sort4_helper(
+ void * clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+ const char *zSql1;
+ const char *zSql2;
+ int nStep;
+ int iStep;
+ int iCksum1 = 0;
+ int iCksum2 = 0;
+ int rc;
+ int iB;
+ sqlite3 *db;
+ sqlite3_stmt *pStmt;
+
+ if( objc!=5 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "DB SQL1 NSTEP SQL2");
+ return TCL_ERROR;
+ }
+
+ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
+ zSql1 = Tcl_GetString(objv[2]);
+ if( Tcl_GetIntFromObj(interp, objv[3], &nStep) ) return TCL_ERROR;
+ zSql2 = Tcl_GetString(objv[4]);
+
+ rc = sqlite3_prepare_v2(db, zSql1, -1, &pStmt, 0);
+ if( rc!=SQLITE_OK ) goto sql_error;
+
+ iB = sqlite3_column_count(pStmt)-1;
+ for(iStep=0; iStep<nStep && SQLITE_ROW==sqlite3_step(pStmt); iStep++){
+ int a = sqlite3_column_int(pStmt, 0);
+ if( a!=sqlite3_column_int(pStmt, iB) ){
+ Tcl_AppendResult(interp, "data error: (a!=b)", 0);
+ return TCL_ERROR;
+ }
+
+ iCksum1 += (iCksum1 << 3) + a;
+ }
+ rc = sqlite3_finalize(pStmt);
+ if( rc!=SQLITE_OK ) goto sql_error;
+
+ rc = sqlite3_prepare_v2(db, zSql2, -1, &pStmt, 0);
+ if( rc!=SQLITE_OK ) goto sql_error;
+ for(iStep=0; SQLITE_ROW==sqlite3_step(pStmt); iStep++){
+ int a = sqlite3_column_int(pStmt, 0);
+ iCksum2 += (iCksum2 << 3) + a;
+ }
+ rc = sqlite3_finalize(pStmt);
+ if( rc!=SQLITE_OK ) goto sql_error;
+
+ if( iCksum1!=iCksum2 ){
+ Tcl_AppendResult(interp, "checksum mismatch", 0);
+ return TCL_ERROR;
+ }
+
+ return TCL_OK;
+ sql_error:
+ Tcl_AppendResult(interp, "sql error: ", sqlite3_errmsg(db), 0);
+ return TCL_ERROR;
+}
+
/*
** Register commands with the TCL interpreter.
#endif
{ "load_static_extension", tclLoadStaticExtensionCmd },
{ "sorter_test_fakeheap", sorter_test_fakeheap },
+ { "sorter_test_sort4_helper", sorter_test_sort4_helper },
};
static int bitmask_size = sizeof(Bitmask)*8;
int i;
} -files {
delete.test delete2.test insert.test rollback.test select1.test
select2.test trans.test update.test vacuum.test types.test
- types2.test types3.test
+ types2.test types3.test sort4.test
} -shutdown {
catch {db close}
sqlite3_shutdown
source $testdir/tester.tcl
set testprefix sort4
+# Configure the sorter to use 3 background threads.
catch { db close }
sqlite3_shutdown
sqlite3_config_worker_threads 3
sqlite3_initialize
reset_db
+# Minimum number of seconds to run for. If the value is 0, each test
+# is run exactly once. Otherwise, tests are repeated until the timeout
+# expires.
+set SORT4TIMEOUT 0
+if {[permutation] == "multithread"} { set SORT4TIMEOUT 300 }
+
#--------------------------------------------------------------------
# Set up a table "t1" containing $nRow rows. Each row contains also
-# contains blob fields that total to at least $nPayload bytes of
-# content.
+# contains blob fields that collectively contain at least $nPayload
+# bytes of content. The table schema is as follows:
+#
+# CREATE TABLE t1(a INTEGER, <extra-columns>, b INTEGER);
+#
+# For each row, the values of columns "a" and "b" are set to the same
+# pseudo-randomly selected integer. The "extra-columns", of which there
+# are at most eight, are named c0, c1, c2 etc. Column c0 contains a 4
+# byte string. Column c1 an 8 byte string. Field c2 16 bytes, and so on.
+#
+# This table is intended to be used for testing queries of the form:
+#
+# SELECT a, <cols>, b FROM t1 ORDER BY a;
+#
+# The test code checks that rows are returned in order, and that the
+# values of "a" and "b" are the same for each row (the idea being that
+# if field "b" at the end of the sorter record has not been corrupted,
+# the rest of the record is probably Ok as well).
#
proc populate_table {nRow nPayload} {
set nCol 0
# Helper for [do_sorter_test]
#
-proc sorter_test {nRow nRead {nPayload 100} {cache_size 10}} {
- db eval "PRAGMA cache_size = $cache_size"
+proc sorter_test {nRow nRead nPayload} {
set res [list]
set nLoad [expr ($nRow > $nRead) ? $nRead : $nRow]
if {$nPayload & $mask} { lappend cols $col }
}
- set n 0
- db eval "SELECT a, [join $cols ,], b FROM t1 WHERE rowid<=$nRow ORDER BY a" {
- if {$a!=$b} { error "a!=b (a=$a b=$b)" }
- lappend res $a
- incr n
- if {$n==$nLoad} break
- }
-
-
- set sql {SELECT a FROM t1 WHERE rowid<=$nRow ORDER BY a LIMIT $nRead}
- if {$res != [db eval $sql]} {
- puts $res
- puts [db eval {SELECT a FROM t1 WHERE rowid<=$nLoad ORDER BY a}]
- error "data no good"
- }
-
+ # Create two SELECT statements. Statement $sql1 uses the sorter to sort
+ # $nRow records of a bit over $nPayload bytes each read from the "t1"
+ # table created by [populate_table] proc above. Rows are sorted in order
+ # of the integer field in each "t1" record.
+ #
+ # The second SQL statement sorts the same set of rows as the first, but
+ # uses a LIMIT clause, causing SQLite to use a temp table instead of the
+ # sorter for sorting.
+ #
+ set sql1 "SELECT a, [join $cols ,], b FROM t1 WHERE rowid<=$nRow ORDER BY a"
+ set sql2 "SELECT a FROM t1 WHERE rowid<=$nRow ORDER BY a LIMIT $nRead"
+
+ # Pass the two SQL statements to a helper command written in C. This
+ # command steps statement $sql1 $nRead times and compares the integer
+ # values in the rows returned with the results of executing $sql2. If
+ # the comparison fails (indicating some bug in the sorter), a Tcl
+ # exception is thrown.
+ #
+ sorter_test_sort4_helper db $sql1 $nRead $sql2
set {} {}
}
set a($s) $val
}
- for {set i 0} {$i < $a(-repeats)} {incr i} {
- set cmd [list sorter_test $a(-rows) $a(-read) $a(-payload) $a(-cachesize)]
- do_test $tn.$i $cmd {}
- }
+ db eval "PRAGMA cache_size = $a(-cachesize)"
+
+ do_test $tn [subst -nocommands {
+ for {set i 0} {[set i] < $a(-repeats)} {incr i} {
+ sorter_test $a(-rows) $a(-read) $a(-payload)
+ }
+ }] {}
+}
+
+proc clock_seconds {} {
+ db one {SELECT strftime('%s')}
}
+#-------------------------------------------------------------------------
+# Begin tests here.
+
+# Create a test database.
do_test 1 {
execsql "PRAGMA page_size = 4096"
populate_table 100000 500
} {}
-do_sorter_test 2 -repeats 10 -rows 1000 -read 100
-do_sorter_test 3 -repeats 10 -rows 100000 -read 1000
-do_sorter_test 4 -repeats 10 -rows 100000 -read 1000 -payload 500
-do_sorter_test 5 -repeats 10 -rows 100000 -read 100000 -payload 8
-do_sorter_test 6 -repeats 10 -rows 100000 -read 10 -payload 8
+set iTimeLimit [expr [clock_seconds] + $SORT4TIMEOUT]
+
+for {set tn 2} {1} {incr tn} {
+ do_sorter_test $tn.2 -repeats 10 -rows 1000 -read 100
+ do_sorter_test $tn.3 -repeats 10 -rows 100000 -read 1000
+ do_sorter_test $tn.4 -repeats 10 -rows 100000 -read 1000 -payload 500
+ do_sorter_test $tn.5 -repeats 10 -rows 100000 -read 100000 -payload 8
+ do_sorter_test $tn.6 -repeats 10 -rows 100000 -read 10 -payload 8
+
+ set iNow [clock_seconds]
+ if {$iNow>=$iTimeLimit} break
+ do_test "$testprefix-([expr $iTimeLimit-$iNow] seconds remain)" {} {}
+}
catch { db close }
sqlite3_shutdown
sqlite3_initialize
finish_test
-