| OLD | NEW |
| (Empty) |
| 1 # 2014 Dec 20 | |
| 2 # | |
| 3 # The author disclaims copyright to this source code. In place of | |
| 4 # a legal notice, here is a blessing: | |
| 5 # | |
| 6 # May you do good and not evil. | |
| 7 # May you find forgiveness for yourself and forgive others. | |
| 8 # May you share freely, never taking more than you give. | |
| 9 # | |
| 10 #*********************************************************************** | |
| 11 # | |
| 12 # Test that focus on incremental merges of segments. | |
| 13 # | |
| 14 | |
| 15 source [file join [file dirname [info script]] fts5_common.tcl] | |
| 16 set testprefix fts5merge | |
| 17 | |
| 18 # If SQLITE_ENABLE_FTS5 is defined, omit this file. | |
| 19 ifcapable !fts5 { | |
| 20 finish_test | |
| 21 return | |
| 22 } | |
| 23 | |
| 24 db func repeat [list string repeat] | |
| 25 | |
| 26 #------------------------------------------------------------------------- | |
| 27 # Create an fts index so that: | |
| 28 # | |
| 29 # * the index consists of two top-level segments | |
| 30 # * each segment contains records related to $nRowPerSeg rows | |
| 31 # * all rows consist of tokens "x" and "y" only. | |
| 32 # | |
| 33 # Then run ('merge', 1) until everything is completely merged. | |
| 34 # | |
| 35 proc do_merge1_test {testname nRowPerSeg} { | |
| 36 set ::nRowPerSeg [expr $nRowPerSeg] | |
| 37 do_execsql_test $testname.0 { | |
| 38 DROP TABLE IF EXISTS x8; | |
| 39 CREATE VIRTUAL TABLE x8 USING fts5(i); | |
| 40 INSERT INTO x8(x8, rank) VALUES('pgsz', 32); | |
| 41 | |
| 42 WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<$::nRowPerSeg) | |
| 43 INSERT INTO x8 SELECT repeat('x y ', i % 16) FROM ii; | |
| 44 | |
| 45 WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<$::nRowPerSeg) | |
| 46 INSERT INTO x8 SELECT repeat('x y ', i % 16) FROM ii; | |
| 47 | |
| 48 INSERT INTO x8(x8, rank) VALUES('automerge', 2); | |
| 49 } | |
| 50 | |
| 51 for {set tn 1} {[lindex [fts5_level_segs x8] 0]>0} {incr tn} { | |
| 52 do_execsql_test $testname.$tn { | |
| 53 INSERT INTO x8(x8, rank) VALUES('merge', 1); | |
| 54 INSERT INTO x8(x8) VALUES('integrity-check'); | |
| 55 } | |
| 56 if {$tn>5} break | |
| 57 } | |
| 58 | |
| 59 do_test $testname.x [list expr "$tn < 5"] 1 | |
| 60 } | |
| 61 | |
| 62 do_merge1_test 1.1 1 | |
| 63 do_merge1_test 1.2 2 | |
| 64 do_merge1_test 1.3 3 | |
| 65 do_merge1_test 1.4 4 | |
| 66 do_merge1_test 1.5 10 | |
| 67 do_merge1_test 1.6 20 | |
| 68 do_merge1_test 1.7 100 | |
| 69 | |
| 70 #------------------------------------------------------------------------- | |
| 71 # | |
| 72 proc do_merge2_test {testname nRow} { | |
| 73 db func rnddoc fts5_rnddoc | |
| 74 | |
| 75 do_execsql_test $testname.0 { | |
| 76 DROP TABLE IF EXISTS x8; | |
| 77 CREATE VIRTUAL TABLE x8 USING fts5(i); | |
| 78 INSERT INTO x8(x8, rank) VALUES('pgsz', 32); | |
| 79 } | |
| 80 | |
| 81 set ::nRow $nRow | |
| 82 do_test $testname.1 { | |
| 83 for {set i 0} {$i < $::nRow} {incr i} { | |
| 84 execsql { INSERT INTO x8 VALUES( rnddoc(($i%16) + 5) ) } | |
| 85 while {[not_merged x8]} { | |
| 86 execsql { | |
| 87 INSERT INTO x8(x8, rank) VALUES('automerge', 2); | |
| 88 INSERT INTO x8(x8, rank) VALUES('merge', 1); | |
| 89 INSERT INTO x8(x8, rank) VALUES('automerge', 16); | |
| 90 INSERT INTO x8(x8) VALUES('integrity-check'); | |
| 91 } | |
| 92 } | |
| 93 } | |
| 94 } {} | |
| 95 } | |
| 96 proc not_merged {tbl} { | |
| 97 set segs [fts5_level_segs $tbl] | |
| 98 foreach s $segs { if {$s>1} { return 1 } } | |
| 99 return 0 | |
| 100 } | |
| 101 | |
| 102 do_merge2_test 2.1 5 | |
| 103 do_merge2_test 2.2 10 | |
| 104 do_merge2_test 2.3 20 | |
| 105 | |
| 106 #------------------------------------------------------------------------- | |
| 107 # Test that an auto-merge will complete any merge that has already been | |
| 108 # started, even if the number of input segments is less than the current | |
| 109 # value of the 'automerge' configuration parameter. | |
| 110 # | |
| 111 db func rnddoc fts5_rnddoc | |
| 112 | |
| 113 do_execsql_test 3.1 { | |
| 114 DROP TABLE IF EXISTS x8; | |
| 115 CREATE VIRTUAL TABLE x8 USING fts5(i); | |
| 116 INSERT INTO x8(x8, rank) VALUES('pgsz', 32); | |
| 117 INSERT INTO x8 VALUES(rnddoc(100)); | |
| 118 INSERT INTO x8 VALUES(rnddoc(100)); | |
| 119 } | |
| 120 do_test 3.2 { | |
| 121 execsql { | |
| 122 INSERT INTO x8(x8, rank) VALUES('automerge', 4); | |
| 123 INSERT INTO x8(x8, rank) VALUES('merge', 1); | |
| 124 } | |
| 125 fts5_level_segs x8 | |
| 126 } {2} | |
| 127 | |
| 128 do_test 3.3 { | |
| 129 execsql { | |
| 130 INSERT INTO x8(x8, rank) VALUES('automerge', 2); | |
| 131 INSERT INTO x8(x8, rank) VALUES('merge', 1); | |
| 132 } | |
| 133 fts5_level_segs x8 | |
| 134 } {2 1} | |
| 135 | |
| 136 do_test 3.4 { | |
| 137 execsql { INSERT INTO x8(x8, rank) VALUES('automerge', 4) } | |
| 138 while {[not_merged x8]} { | |
| 139 execsql { INSERT INTO x8(x8, rank) VALUES('merge', 1) } | |
| 140 } | |
| 141 fts5_level_segs x8 | |
| 142 } {0 1} | |
| 143 | |
| 144 #------------------------------------------------------------------------- | |
| 145 # | |
| 146 proc mydoc {} { | |
| 147 set x [lindex {a b c d e f g h i j} [expr int(rand()*10)]] | |
| 148 return [string repeat "$x " 30] | |
| 149 } | |
| 150 db func mydoc mydoc | |
| 151 | |
| 152 proc mycount {} { | |
| 153 set res [list] | |
| 154 foreach x {a b c d e f g h i j} { | |
| 155 lappend res [db one {SELECT count(*) FROM x8 WHERE x8 MATCH $x}] | |
| 156 } | |
| 157 set res | |
| 158 } | |
| 159 | |
| 160 #1 32 | |
| 161 foreach {tn pgsz} { | |
| 162 2 1000 | |
| 163 } { | |
| 164 do_execsql_test 4.$tn.1 { | |
| 165 DROP TABLE IF EXISTS x8; | |
| 166 CREATE VIRTUAL TABLE x8 USING fts5(i); | |
| 167 INSERT INTO x8(x8, rank) VALUES('pgsz', $pgsz); | |
| 168 } | |
| 169 | |
| 170 do_execsql_test 4.$tn.2 { | |
| 171 INSERT INTO x8(x8, rank) VALUES('merge', 1); | |
| 172 } | |
| 173 | |
| 174 do_execsql_test 4.$tn.3 { | |
| 175 WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<100) | |
| 176 INSERT INTO x8 SELECT mydoc() FROM ii; | |
| 177 WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<100) | |
| 178 INSERT INTO x8 SELECT mydoc() FROM ii; | |
| 179 INSERT INTO x8(x8, rank) VALUES('automerge', 2); | |
| 180 } | |
| 181 | |
| 182 set expect [mycount] | |
| 183 for {set i 0} {$i < 20} {incr i} { | |
| 184 do_test 4.$tn.4.$i { | |
| 185 execsql { INSERT INTO x8(x8, rank) VALUES('merge', 1); } | |
| 186 mycount | |
| 187 } $expect | |
| 188 break | |
| 189 } | |
| 190 # db eval {SELECT fts5_decode(rowid, block) AS r FROM x8_data} { puts $r } | |
| 191 } | |
| 192 | |
| 193 finish_test | |
| 194 | |
| OLD | NEW |