OLD | NEW |
(Empty) | |
| 1 # 2016 March 8 |
| 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 |
| 13 set testdir [file dirname $argv0] |
| 14 source $testdir/tester.tcl |
| 15 source $testdir/fts3_common.tcl |
| 16 set ::testprefix fts4opt |
| 17 |
| 18 # If SQLITE_ENABLE_FTS3 is defined, omit this file. |
| 19 ifcapable !fts3 { |
| 20 finish_test |
| 21 return |
| 22 } |
| 23 |
| 24 # Create the fts_kjv_genesis procedure which fills and FTS3/4 table |
| 25 # with the complete text of the Book of Genesis. |
| 26 # |
| 27 source $testdir/genesis.tcl |
| 28 |
| 29 do_execsql_test 1.0 { CREATE TABLE t1(docid, words) } |
| 30 fts_kjv_genesis |
| 31 |
| 32 #------------------------------------------------------------------------- |
| 33 # Argument $db is an open database handle. $tbl is the name of an FTS3/4 |
| 34 # table with the database. This command rearranges the contents of the |
| 35 # %_segdir table so that all segments within each index are on the same |
| 36 # level. This means that the 'merge' command can then be used for an |
| 37 # incremental optimize routine. |
| 38 # |
| 39 proc prepare_for_optimize {db tbl} { |
| 40 $db eval [string map [list % $tbl] { |
| 41 BEGIN; |
| 42 CREATE TEMP TABLE tmp_segdir( |
| 43 level, idx, start_block, leaves_end_block, end_block, root |
| 44 ); |
| 45 |
| 46 INSERT INTO temp.tmp_segdir |
| 47 SELECT |
| 48 1024*(o.level / 1024) + 32, -- level |
| 49 sum(o.level<i.level OR (o.level=i.level AND o.idx>i.idx)), -- idx |
| 50 o.start_block, o.leaves_end_block, o.end_block, o.root -- other |
| 51 FROM %_segdir o, %_segdir i |
| 52 WHERE (o.level / 1024) = (i.level / 1024) |
| 53 GROUP BY o.level, o.idx; |
| 54 |
| 55 DELETE FROM %_segdir; |
| 56 INSERT INTO %_segdir SELECT * FROM temp.tmp_segdir; |
| 57 DROP TABLE temp.tmp_segdir; |
| 58 |
| 59 COMMIT; |
| 60 }] |
| 61 } |
| 62 |
| 63 do_test 1.1 { |
| 64 execsql { CREATE VIRTUAL TABLE t2 USING fts4(words, prefix="1,2,3") } |
| 65 foreach {docid words} [db eval { SELECT * FROM t1 }] { |
| 66 execsql { INSERT INTO t2(docid, words) VALUES($docid, $words) } |
| 67 } |
| 68 } {} |
| 69 |
| 70 do_execsql_test 1.2 { |
| 71 SELECT level, count(*) FROM t2_segdir GROUP BY level |
| 72 } { |
| 73 0 13 1 15 2 5 |
| 74 1024 13 1025 15 1026 5 |
| 75 2048 13 2049 15 2050 5 |
| 76 3072 13 3073 15 3074 5 |
| 77 } |
| 78 |
| 79 do_execsql_test 1.3 { INSERT INTO t2(t2) VALUES('integrity-check') } |
| 80 prepare_for_optimize db t2 |
| 81 do_execsql_test 1.4 { INSERT INTO t2(t2) VALUES('integrity-check') } |
| 82 |
| 83 do_execsql_test 1.5 { |
| 84 SELECT level, count(*) FROM t2_segdir GROUP BY level |
| 85 } { |
| 86 32 33 |
| 87 1056 33 |
| 88 2080 33 |
| 89 3104 33 |
| 90 } |
| 91 |
| 92 do_test 1.6 { |
| 93 while 1 { |
| 94 set tc1 [db total_changes] |
| 95 execsql { INSERT INTO t2(t2) VALUES('merge=5,2') } |
| 96 set tc2 [db total_changes] |
| 97 if {($tc2 - $tc1) < 2} break |
| 98 } |
| 99 execsql { SELECT level, count(*) FROM t2_segdir GROUP BY level } |
| 100 } {33 1 1057 1 2081 1 3105 1} |
| 101 do_execsql_test 1.7 { INSERT INTO t2(t2) VALUES('integrity-check') } |
| 102 |
| 103 do_execsql_test 1.8 { |
| 104 INSERT INTO t2(words) SELECT words FROM t1; |
| 105 SELECT level, count(*) FROM t2_segdir GROUP BY level; |
| 106 } {0 2 1024 2 2048 2 3072 2} |
| 107 |
| 108 #------------------------------------------------------------------------- |
| 109 |
| 110 do_execsql_test 2.0 { |
| 111 DELETE FROM t2; |
| 112 } |
| 113 do_test 2.1 { |
| 114 foreach {docid words} [db eval { SELECT * FROM t1 }] { |
| 115 execsql { INSERT INTO t2(docid, words) VALUES($docid, $words) } |
| 116 } |
| 117 |
| 118 set i 0 |
| 119 foreach {docid words} [db eval { SELECT * FROM t1 }] { |
| 120 if {[incr i] % 2} { execsql { DELETE FROM t2 WHERE docid = $docid } } |
| 121 } |
| 122 |
| 123 set i 0 |
| 124 foreach {docid words} [db eval { SELECT * FROM t1 }] { |
| 125 if {[incr i] % 3} { |
| 126 execsql { INSERT OR REPLACE INTO t2(docid, words) VALUES($docid, $words) } |
| 127 } |
| 128 } |
| 129 } {} |
| 130 |
| 131 do_execsql_test 2.2 { |
| 132 SELECT level, count(*) FROM t2_segdir GROUP BY level |
| 133 } { |
| 134 0 10 1 15 2 12 |
| 135 1024 10 1025 15 1026 12 |
| 136 2048 10 2049 15 2050 12 |
| 137 3072 10 3073 15 3074 12 |
| 138 } |
| 139 |
| 140 do_execsql_test 2.3 { INSERT INTO t2(t2) VALUES('integrity-check') } |
| 141 prepare_for_optimize db t2 |
| 142 do_execsql_test 2.4 { INSERT INTO t2(t2) VALUES('integrity-check') } |
| 143 |
| 144 do_execsql_test 2.5 { |
| 145 SELECT level, count(*) FROM t2_segdir GROUP BY level |
| 146 } { |
| 147 32 37 |
| 148 1056 37 |
| 149 2080 37 |
| 150 3104 37 |
| 151 } |
| 152 |
| 153 do_test 2.6 { |
| 154 while 1 { |
| 155 set tc1 [db total_changes] |
| 156 execsql { INSERT INTO t2(t2) VALUES('merge=5,2') } |
| 157 set tc2 [db total_changes] |
| 158 if {($tc2 - $tc1) < 2} break |
| 159 } |
| 160 execsql { SELECT level, count(*) FROM t2_segdir GROUP BY level } |
| 161 } {33 1 1057 1 2081 1 3105 1} |
| 162 do_execsql_test 2.7 { INSERT INTO t2(t2) VALUES('integrity-check') } |
| 163 |
| 164 do_execsql_test 2.8 { |
| 165 INSERT INTO t2(words) SELECT words FROM t1; |
| 166 SELECT level, count(*) FROM t2_segdir GROUP BY level; |
| 167 } {0 2 1024 2 2048 2 3072 2} |
| 168 |
| 169 #------------------------------------------------------------------------- |
| 170 # Check that 'optimize' works when there is data in the in-memory hash |
| 171 # table, but no segments at all on disk. |
| 172 # |
| 173 do_execsql_test 3.1 { |
| 174 CREATE VIRTUAL TABLE fts USING fts4 (t); |
| 175 INSERT INTO fts (fts) VALUES ('optimize'); |
| 176 } |
| 177 do_execsql_test 3.2 { |
| 178 INSERT INTO fts(fts) VALUES('integrity-check'); |
| 179 SELECT count(*) FROM fts_segdir; |
| 180 } {0} |
| 181 do_execsql_test 3.3 { |
| 182 BEGIN; |
| 183 INSERT INTO fts (rowid, t) VALUES (2, 'test'); |
| 184 INSERT INTO fts (fts) VALUES ('optimize'); |
| 185 COMMIT; |
| 186 SELECT level, idx FROM fts_segdir; |
| 187 } {0 0} |
| 188 do_execsql_test 3.4 { |
| 189 INSERT INTO fts(fts) VALUES('integrity-check'); |
| 190 SELECT rowid FROM fts WHERE fts MATCH 'test'; |
| 191 } {2} |
| 192 do_execsql_test 3.5 { |
| 193 INSERT INTO fts (fts) VALUES ('optimize'); |
| 194 INSERT INTO fts(fts) VALUES('integrity-check'); |
| 195 } |
| 196 do_test 3.6 { |
| 197 set c1 [db total_changes] |
| 198 execsql { INSERT INTO fts (fts) VALUES ('optimize') } |
| 199 expr {[db total_changes] - $c1} |
| 200 } {1} |
| 201 do_test 3.7 { |
| 202 execsql { INSERT INTO fts (rowid, t) VALUES (3, 'xyz') } |
| 203 set c1 [db total_changes] |
| 204 execsql { INSERT INTO fts (fts) VALUES ('optimize') } |
| 205 expr {([db total_changes] - $c1) > 1} |
| 206 } {1} |
| 207 do_test 3.8 { |
| 208 set c1 [db total_changes] |
| 209 execsql { INSERT INTO fts (fts) VALUES ('optimize') } |
| 210 expr {[db total_changes] - $c1} |
| 211 } {1} |
| 212 |
| 213 finish_test |
OLD | NEW |