mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Re-implement the core of the multi-threaded sorter tests in sort4.test using C. Run each test in sort4.test ten times, or repeat all tests for 300 seconds as part of the "multithread" permutation test.
FossilOrigin-Name: 208b2b04d4d282bec4424ea7160a123ba549d118
This commit is contained in:
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
||||
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
|
||||
@ -228,7 +228,7 @@ F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
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
|
||||
@ -741,7 +741,7 @@ F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
|
||||
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
|
||||
@ -824,7 +824,7 @@ F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24
|
||||
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
|
||||
@ -1171,7 +1171,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
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
|
||||
|
@ -1 +1 @@
|
||||
9cc364c42cc64ab7b55b5c55e303fb63a456cf00
|
||||
208b2b04d4d282bec4424ea7160a123ba549d118
|
74
src/test1.c
74
src/test1.c
@ -6370,6 +6370,79 @@ static int sorter_test_fakeheap(
|
||||
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.
|
||||
@ -6604,6 +6677,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
#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;
|
||||
|
@ -469,7 +469,7 @@ test_suite "multithread" -description {
|
||||
} -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
|
||||
|
101
test/sort4.test
101
test/sort4.test
@ -18,16 +18,39 @@ set testdir [file dirname $argv0]
|
||||
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
|
||||
@ -57,8 +80,7 @@ proc populate_table {nRow nPayload} {
|
||||
|
||||
# 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]
|
||||
@ -72,22 +94,25 @@ proc sorter_test {nRow nRead {nPayload 100} {cache_size 10}} {
|
||||
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 {} {}
|
||||
}
|
||||
|
||||
@ -119,22 +144,41 @@ proc do_sorter_test {tn args} {
|
||||
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
|
||||
@ -142,4 +186,3 @@ sqlite3_config_worker_threads 0
|
||||
sqlite3_initialize
|
||||
finish_test
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user