ferret 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. data/ext/Makefile +2 -2
  2. data/ext/ferret.c +27 -2
  3. data/ext/ferret.h +59 -16
  4. data/ext/ferret_ext.so +0 -0
  5. data/ext/index_io.c +72 -77
  6. data/ext/priority_queue.c +150 -145
  7. data/ext/ram_directory.c +47 -42
  8. data/ext/segment_merge_queue.c +4 -8
  9. data/ext/segment_term_enum.c +324 -0
  10. data/ext/similarity.c +59 -0
  11. data/ext/string_helper.c +2 -2
  12. data/ext/tags +150 -46
  13. data/ext/term.c +107 -152
  14. data/ext/term_buffer.c +105 -174
  15. data/ext/term_infos_reader.c +54 -0
  16. data/ext/terminfo.c +160 -0
  17. data/ext/token.c +93 -0
  18. data/lib/ferret.rb +1 -1
  19. data/lib/ferret/analysis/analyzers.rb +18 -0
  20. data/lib/ferret/analysis/standard_tokenizer.rb +19 -14
  21. data/lib/ferret/analysis/token.rb +8 -1
  22. data/lib/ferret/analysis/tokenizers.rb +10 -5
  23. data/lib/ferret/document/field.rb +33 -11
  24. data/lib/ferret/index/document_writer.rb +3 -2
  25. data/lib/ferret/index/field_infos.rb +38 -12
  26. data/lib/ferret/index/fields_io.rb +10 -4
  27. data/lib/ferret/index/index.rb +20 -4
  28. data/lib/ferret/index/index_reader.rb +19 -4
  29. data/lib/ferret/index/index_writer.rb +1 -1
  30. data/lib/ferret/index/multi_reader.rb +21 -7
  31. data/lib/ferret/index/segment_merge_info.rb +24 -22
  32. data/lib/ferret/index/segment_merge_queue.rb +2 -2
  33. data/lib/ferret/index/segment_merger.rb +28 -11
  34. data/lib/ferret/index/segment_reader.rb +19 -4
  35. data/lib/ferret/index/segment_term_enum.rb +3 -11
  36. data/lib/ferret/index/term_buffer.rb +13 -16
  37. data/lib/ferret/index/term_doc_enum.rb +8 -5
  38. data/lib/ferret/index/term_enum.rb +2 -2
  39. data/lib/ferret/index/term_info.rb +1 -5
  40. data/lib/ferret/index/term_infos_io.rb +2 -0
  41. data/lib/ferret/query_parser/query_parser.tab.rb +7 -7
  42. data/lib/ferret/search/phrase_scorer.rb +0 -1
  43. data/lib/ferret/search/similarity.rb +2 -2
  44. data/lib/ferret/search/term_scorer.rb +2 -2
  45. data/lib/ferret/store/directory.rb +2 -0
  46. data/lib/ferret/store/fs_store.rb +16 -3
  47. data/lib/ferret/store/ram_store.rb +2 -2
  48. data/test/unit/document/tc_field.rb +9 -0
  49. data/test/unit/index/tc_field_infos.rb +29 -21
  50. data/test/unit/index/tc_index.rb +44 -7
  51. data/test/unit/index/tc_term_buffer.rb +3 -3
  52. data/test/unit/index/tc_term_info.rb +1 -1
  53. data/test/unit/query_parser/tc_query_parser.rb +1 -1
  54. data/test/unit/search/tc_index_searcher.rb +3 -0
  55. data/test/unit/store/tc_fs_store.rb +47 -16
  56. data/test/unit/store/tc_ram_store.rb +1 -1
  57. metadata +8 -3
@@ -69,7 +69,6 @@ module Ferret::Search
69
69
  end
70
70
 
71
71
  def score()
72
- #puts("scoring #{@first.doc}")
73
72
  raw = similarity().tf(@freq) * @value # raw score
74
73
  return raw * Similarity.decode_norm(@norms[@first.doc]) # normalize
75
74
  end
@@ -39,13 +39,13 @@ module Ferret::Search
39
39
  end
40
40
  mantissa = b & 0x07 # 0x07 = 7 = 0b00000111
41
41
  exponent = (b >> 3) & 0x1F # 0x1f = 31 = 0b00011111
42
- return [0,0,(mantissa << 5),(exponent+48)].pack("cccc").unpack("f")[0]
42
+ return [0,0,(mantissa << 5),(exponent+48)].pack("cccc").unpack("e")[0]
43
43
  end
44
44
 
45
45
  def Similarity.float_to_byte(f)
46
46
  if (f <= 0.0) then return 0 end
47
47
 
48
- bits = [f].pack("f").unpack("cccc")
48
+ bits = [f].pack("e").unpack("cccc")
49
49
  mantissa = (bits[2] & 0xEf) >> 5
50
50
  exponent = (bits[3] - 48)
51
51
 
@@ -17,8 +17,8 @@ module Ferret::Search
17
17
  super(similarity)
18
18
 
19
19
  @doc = 0
20
- @docs = Array.new(32, 0) # buffered doc numbers
21
- @freqs = Array.new(32, 0) # buffered term freqs
20
+ @docs = Array.new(SCORE_CACHE_SIZE, 0) # buffered doc numbers
21
+ @freqs = Array.new(SCORE_CACHE_SIZE, 0) # buffered term freqs
22
22
  @pointer = @pointer_max = 0;
23
23
  @score_cache = Array.new(SCORE_CACHE_SIZE)
24
24
 
@@ -14,6 +14,8 @@ module Ferret::Store
14
14
  # called _open_input_ If there is a risk of simultaneous modifications of
15
15
  # the files then locks should be used. See Lock to find out how.
16
16
  class Directory
17
+ LOCK_PREFIX = "ferret-"
18
+
17
19
  # returns an array of strings, one for each file in the directory
18
20
  def each # :yeilds: file_name
19
21
  raise NotImplementedError
@@ -192,6 +192,7 @@ module Ferret::Store
192
192
  if (@ref_count <= 0) then
193
193
  @@Directories.synchronize do
194
194
  @@Directories.delete(@dir.path)
195
+ close_internal
195
196
  end
196
197
  end
197
198
  end
@@ -206,6 +207,12 @@ module Ferret::Store
206
207
  # pass the name of the file that we are going to lock
207
208
  def initialize(lock_file)
208
209
  @lock_file = lock_file
210
+ #@clean = FSLock.make_finalizer(lock_file)
211
+ @clean = lambda { File.delete(lock_file) rescue nil}
212
+ end
213
+
214
+ def FSLock.make_finalizer(lock_file)
215
+ lambda { File.delete(lock_file) rescue nil}
209
216
  end
210
217
 
211
218
  # obtain the lock on the data source
@@ -216,6 +223,7 @@ module Ferret::Store
216
223
  # create a file if none exists. If one already exists
217
224
  # then someone beat us to the lock so return false
218
225
  File.open(@lock_file, File::WRONLY|File::EXCL|File::CREAT) {|f|}
226
+ ObjectSpace.define_finalizer(self, @clean)
219
227
  return true
220
228
  rescue SystemCallError
221
229
  # lock was not obtained so sleep for timeout then try again.
@@ -223,7 +231,7 @@ module Ferret::Store
223
231
  end
224
232
  end
225
233
  # lock could not be obtained so raise an exception
226
- raise "could not obtain lock: " + @lock_file.to_s
234
+ raise "could not obtain lock: #{@lock_file}"
227
235
  end
228
236
 
229
237
  # Release the lock on the data source. Returns true if successful.
@@ -231,6 +239,7 @@ module Ferret::Store
231
239
  return if FSDirectory.locks_disabled?
232
240
  begin
233
241
  File.delete(@lock_file)
242
+ ObjectSpace.undefine_finalizer(self)
234
243
  rescue SystemCallError
235
244
  # maybe we tried to release a lock that wasn't locked. This
236
245
  # isn't critical so just return false
@@ -246,7 +255,8 @@ module Ferret::Store
246
255
  end
247
256
  end
248
257
 
249
- # A file system output stream extending OutputStream to read from the file system
258
+ # A file system output stream extending OutputStream to read from the file
259
+ # system
250
260
  class FSIndexOutput < BufferedIndexOutput
251
261
  def initialize(path)
252
262
  super()
@@ -330,7 +340,7 @@ module Ferret::Store
330
340
 
331
341
  # returns the lock prefix for this directory
332
342
  def lock_prefix
333
- 'ferret-' + Digest::MD5.hexdigest(@dir.path)
343
+ LOCK_PREFIX + Digest::MD5.hexdigest(@dir.path)
334
344
  end
335
345
 
336
346
  # Unfortunately, on Windows, Dir does not refresh when rewind is called
@@ -347,6 +357,9 @@ module Ferret::Store
347
357
  @lock_dir = tmp
348
358
  end
349
359
 
360
+ # This method is only used by the c extension to free the directory
361
+ def close_internal
362
+ end
350
363
  #end private
351
364
  end
352
365
  end
@@ -25,7 +25,7 @@ module Ferret::Store
25
25
  # returns an array of strings, one for each file in the directory
26
26
  def each()
27
27
  @files.each do |path, file|
28
- next if file =~ Regexp.new('^rubylock-')
28
+ next if file =~ /#{LOCK_PREFIX}/
29
29
  yield file
30
30
  end
31
31
  end
@@ -89,7 +89,7 @@ module Ferret::Store
89
89
 
90
90
  # Construct a Lock.
91
91
  def make_lock(name)
92
- RAMLock.new("rubylock-" + name, self)
92
+ RAMLock.new(LOCK_PREFIX + name, self)
93
93
  end
94
94
 
95
95
 
@@ -15,6 +15,7 @@ class FieldTest < Test::Unit::TestCase
15
15
  assert_equal("TOKENIZED", Field::Index::TOKENIZED.to_s)
16
16
  assert_equal("UNTOKENIZED", Field::Index::UNTOKENIZED.to_s)
17
17
  assert_equal("NO", Field::Index::NO.to_s)
18
+ assert_equal("NO_NORMS", Field::Index::NO_NORMS.to_s)
18
19
  end
19
20
 
20
21
  def test_term_vector()
@@ -36,6 +37,7 @@ class FieldTest < Test::Unit::TestCase
36
37
  assert_equal(false, f.store_term_vector?)
37
38
  assert_equal(false, f.store_offsets?)
38
39
  assert_equal(false, f.store_positions?)
40
+ assert_equal(false, f.omit_norms?)
39
41
  assert_equal(false, f.binary?)
40
42
  assert_equal("stored/compressed,indexed,tokenized,<name:value>", f.to_s)
41
43
  end
@@ -53,7 +55,13 @@ class FieldTest < Test::Unit::TestCase
53
55
  f.index = Field::Index::NO
54
56
  assert_equal(false, f.indexed?)
55
57
  assert_equal(false, f.tokenized?)
58
+ assert_equal(false, f.omit_norms?)
56
59
  assert_equal("stored/compressed,<name:value>", f.to_s)
60
+ f.index = Field::Index::NO_NORMS
61
+ assert_equal(true, f.indexed?)
62
+ assert_equal(false, f.tokenized?)
63
+ assert_equal(true, f.omit_norms?)
64
+ assert_equal("stored/compressed,indexed,omit_norms,<name:value>", f.to_s)
57
65
  end
58
66
 
59
67
  def test_set_term_vector()
@@ -79,6 +87,7 @@ class FieldTest < Test::Unit::TestCase
79
87
  assert_equal(false, f.store_term_vector?)
80
88
  assert_equal(false, f.store_offsets?)
81
89
  assert_equal(false, f.store_positions?)
90
+ assert_equal(false, f.omit_norms?)
82
91
  assert_equal(true, f.binary?)
83
92
  assert_equal("stored/uncompressed,binary,<name:#{bin}>", f.to_s)
84
93
  end
@@ -4,13 +4,14 @@ class FieldInfosTest < Test::Unit::TestCase
4
4
  include Ferret::Index
5
5
 
6
6
  def test_field_info()
7
- fi = FieldInfo.new("name", true, 1, true, true, true)
7
+ fi = FieldInfo.new("name", true, 1, true, true, true, true)
8
8
  assert_equal(fi.name, "name")
9
9
  assert_equal(fi.number, 1)
10
10
  assert(fi.indexed?)
11
11
  assert(fi.store_term_vector?)
12
12
  assert(fi.store_offsets?)
13
13
  assert(fi.store_positions?)
14
+ assert(fi.omit_norms?)
14
15
 
15
16
  fi.name = "hello"
16
17
  fi.indexed = false
@@ -18,6 +19,7 @@ class FieldInfosTest < Test::Unit::TestCase
18
19
  fi.store_term_vector = false
19
20
  fi.store_offset = false
20
21
  fi.store_position = false
22
+ fi.omit_norms = false
21
23
 
22
24
  assert_equal(fi.name, "hello")
23
25
  assert_equal(fi.number, 2)
@@ -25,49 +27,53 @@ class FieldInfosTest < Test::Unit::TestCase
25
27
  assert(!fi.store_term_vector?)
26
28
  assert(!fi.store_offsets?)
27
29
  assert(!fi.store_positions?)
30
+ assert(!fi.omit_norms?)
28
31
 
29
- fi.set!(true, true, true, true)
32
+ fi.set!(true, true, true, true, true)
30
33
  assert(fi.indexed?)
31
34
  assert(fi.store_term_vector?)
32
35
  assert(fi.store_offsets?)
33
36
  assert(fi.store_positions?)
37
+ assert(fi.omit_norms?)
34
38
 
35
39
  fi = FieldInfo.new("name", true, 1, true)
36
40
  assert(!fi.store_offsets?)
37
41
  assert(!fi.store_positions?)
42
+ assert(!fi.omit_norms?)
38
43
  end
39
44
 
40
- def fi_test_attr(fi, name, number, indexed, store_tv, store_pos, store_off)
45
+ def fi_test_attr(fi, name, number, indexed, store_tv, store_pos, store_off, omit_norms)
41
46
  assert_equal(name, fi.name)
42
47
  assert_equal(number, fi.number)
43
48
  assert_equal(indexed, fi.indexed?)
44
49
  assert_equal(store_tv, fi.store_term_vector?)
45
50
  assert_equal(store_pos, fi.store_positions?)
46
51
  assert_equal(store_off, fi.store_offsets?)
52
+ assert_equal(omit_norms, fi.omit_norms?)
47
53
  end
48
54
 
49
55
  def test_fis_add()
50
56
  fis = FieldInfos.new()
51
57
  fi = fis.add("field1", false)
52
- fi_test_attr(fi, "field1", 0, false, false, false, false)
58
+ fi_test_attr(fi, "field1", 0, false, false, false, false, false)
53
59
  assert_equal(1, fis.size)
54
60
 
55
61
  fi = fis.add("field1", true, true)
56
- fi_test_attr(fi, "field1", 0, true, true, false, false)
62
+ fi_test_attr(fi, "field1", 0, true, true, false, false, false)
57
63
  assert_equal(1, fis.size)
58
64
 
59
65
  fi = fis.add("field2", false)
60
- fi_test_attr(fi, "field2", 1, false, false, false, false)
66
+ fi_test_attr(fi, "field2", 1, false, false, false, false, false)
61
67
  assert_equal(2, fis.size)
62
68
 
63
- fi = fis.add("field1", true, true, true, true)
69
+ fi = fis.add("field1", true, true, true, true, true)
64
70
  assert_equal(fi, fis[fi.number])
65
71
  assert_equal(fi, fis["field1"])
66
72
  assert_equal(0, fis.field_number("field1"))
67
73
  assert_equal(1, fis.field_number("field2"))
68
74
  assert_equal(FieldInfos::NOT_A_FIELD, fis.field_number("field3"))
69
75
  assert_equal(nil, fis["field3"])
70
- fi_test_attr(fi, "field1", 0, true, true, true, true)
76
+ fi_test_attr(fi, "field1", 0, true, true, true, true, false)
71
77
  assert_equal(2, fis.size)
72
78
  end
73
79
 
@@ -90,7 +96,7 @@ class FieldInfosTest < Test::Unit::TestCase
90
96
  assert(! fis.has_vectors?)
91
97
  fis.add("random_field")
92
98
  assert(! fis.has_vectors?)
93
- fis.add("store_term_vector_field", true, true, false, false)
99
+ fis.add("store_term_vector_field", true, true, false, false, false)
94
100
  assert(fis.has_vectors?)
95
101
  end
96
102
 
@@ -98,22 +104,24 @@ class FieldInfosTest < Test::Unit::TestCase
98
104
  def test_fis_rw()
99
105
  fis = FieldInfos.new()
100
106
  dir = Ferret::Store::RAMDirectory.new()
101
- fis.add("field1", false, false, false, false)
102
- fis.add("field2", true, false, false, false)
103
- fis.add("field3", true, true, false, false)
104
- fis.add("field4", true, true, true, false)
105
- fis.add("field5", true, true, true, true)
107
+ fis.add("field1", false, false, false, false, true)
108
+ fis.add("field2", true, false, false, false, true)
109
+ fis.add("field3", true, true, false, false, true)
110
+ fis.add("field4", true, true, true, false, true)
111
+ fis.add("field5", true, true, true, true, true)
112
+ fis.add("field6", true, true, true, true, false)
106
113
  fis.write_to_dir(dir, "fis_rw.test")
107
114
  fis = nil
108
115
 
109
116
  fis = FieldInfos.new(dir, "fis_rw.test")
110
- fi_test_attr(fis[0], "field1", 0, false, false, false, false)
111
- fi_test_attr(fis[1], "field2", 1, true, false, false, false)
112
- fi_test_attr(fis[2], "field3", 2, true, true, false, false)
113
- fi_test_attr(fis[3], "field4", 3, true, true, true, false)
114
- fi_test_attr(fis[4], "field5", 4, true, true, true, true)
115
-
116
- assert_equal(5, fis.size)
117
+ fi_test_attr(fis[0], "field1", 0, false, false, false, false, true)
118
+ fi_test_attr(fis[1], "field2", 1, true, false, false, false, true)
119
+ fi_test_attr(fis[2], "field3", 2, true, true, false, false, true)
120
+ fi_test_attr(fis[3], "field4", 3, true, true, true, false, true)
121
+ fi_test_attr(fis[4], "field5", 4, true, true, true, true, true)
122
+ fi_test_attr(fis[5], "field6", 5, true, true, true, true, false)
123
+
124
+ assert_equal(6, fis.size)
117
125
  end
118
126
 
119
127
  end
@@ -8,7 +8,6 @@ class IndexTest < Test::Unit::TestCase
8
8
  include Ferret::Document
9
9
 
10
10
  def setup()
11
- @qp = Ferret::QueryParser.new()
12
11
  end
13
12
 
14
13
  def tear_down()
@@ -81,7 +80,7 @@ class IndexTest < Test::Unit::TestCase
81
80
  {"def_field" => "one two"},
82
81
  {"def_field" => "two", :field2 => "three", "field3" => "four"},
83
82
  {"def_field" => "one multi2"},
84
- {"def_field" => "two", :field2 => "three multi2", "field3" => "five multi"}
83
+ {"def_field" => "two", :field2 => "this three multi2", "field3" => "five multi"}
85
84
  ]
86
85
  data.each {|doc| index << doc }
87
86
  q = "one AND two"
@@ -110,6 +109,7 @@ class IndexTest < Test::Unit::TestCase
110
109
  doc["field2"] = "dave"
111
110
  index << doc
112
111
  check_results(index, q, [6, 7])
112
+ check_results(index, "*:this", [])
113
113
  assert_equal(8, index.size)
114
114
  assert_equal("dave", index[7]["field2"])
115
115
  index.optimize
@@ -129,28 +129,39 @@ class IndexTest < Test::Unit::TestCase
129
129
  def test_ram_index
130
130
  index = Index.new(:default_field => "def_field")
131
131
  do_test_index_with_array(index)
132
+ index.close
133
+
132
134
  index = Index.new(:default_field => "def_field")
133
135
  do_test_index_with_hash(index)
136
+ index.close
137
+
134
138
  index = Index.new(:default_field => "def_field")
135
139
  do_test_index_with_doc_array(index)
140
+ index.close
136
141
  end
137
142
 
138
143
  def test_fs_index
139
144
  fs_path = File.expand_path(File.join(File.dirname(__FILE__), '../../temp/fsdir'))
140
- `rm -rf #{File.join(fs_path, "*")}`
145
+ Dir[File.join(fs_path, "*")].each {|path| begin File.delete(path) rescue nil end}
141
146
  assert_raise(Errno::ENOENT) {Index.new(:path => fs_path, :create_if_missing => false, :default_field => "def_field")}
142
147
  index = Index.new(:path => fs_path, :default_field => "def_field")
143
148
  do_test_index_with_array(index)
144
- `rm -rf #{File.join(fs_path, "*")}`
145
- index = Index.new(:path => fs_path, :create => true, :default_field => "def_field")
149
+ index.close
150
+
151
+ Dir[File.join(fs_path, "*")].each {|path| begin File.delete(path) rescue nil end}
152
+ index = Index.new(:path => fs_path, :default_field => "def_field")
146
153
  do_test_index_with_hash(index)
147
- index = Index.new(:path => fs_path, :create => true, :default_field => "def_field")
154
+ index.close
155
+
156
+ Dir[File.join(fs_path, "*")].each {|path| begin File.delete(path) rescue nil end}
157
+ index = Index.new(:path => fs_path, :default_field => "def_field")
148
158
  do_test_index_with_doc_array(index)
159
+ index.close
149
160
  end
150
161
 
151
162
  def test_fs_index_is_persistant
152
163
  fs_path = File.expand_path(File.join(File.dirname(__FILE__), '../../temp/fsdir'))
153
- `rm -rf #{File.join(fs_path, "*")}`
164
+ Dir[File.join(fs_path, "*")].each {|path| begin File.delete(path) rescue nil end}
154
165
  data = [
155
166
  {"def_field" => "one two", :id => "me"},
156
167
  {"def_field" => "one", :field2 => "three"},
@@ -165,9 +176,11 @@ class IndexTest < Test::Unit::TestCase
165
176
  data.each {|doc| index << doc }
166
177
  assert_equal(8, index.size)
167
178
  index.close
179
+
168
180
  index = Index.new(:path => fs_path, :create_if_missing => false)
169
181
  assert_equal(8, index.size)
170
182
  assert_equal("four", index[5]["field3"])
183
+ index.close
171
184
  end
172
185
 
173
186
  def test_merging_indexes
@@ -246,6 +259,7 @@ class IndexTest < Test::Unit::TestCase
246
259
  index3.close
247
260
  dir3.close
248
261
  assert_equal("golf", index[15]["f"])
262
+ index.close
249
263
  end
250
264
 
251
265
  def test_persist_index
@@ -310,6 +324,7 @@ class IndexTest < Test::Unit::TestCase
310
324
  iw.close()
311
325
  assert_equal(3, index.size)
312
326
  assert_equal("content3", index[2]["f"])
327
+ index.close
313
328
  end
314
329
 
315
330
  def test_delete
@@ -340,6 +355,7 @@ class IndexTest < Test::Unit::TestCase
340
355
  index.query_delete("cat:/cat1*")
341
356
  assert_equal(3, index.size)
342
357
  assert_equal(0, index.search("cat:/cat1*").size)
358
+ index.close
343
359
  end
344
360
 
345
361
  def test_update
@@ -390,6 +406,7 @@ class IndexTest < Test::Unit::TestCase
390
406
  assert_equal("cool", index["3"][:tag])
391
407
  assert_equal("cool", index["4"][:tag])
392
408
  assert_equal(4, index.search("tag:cool").size)
409
+ index.close
393
410
  end
394
411
 
395
412
  def test_index_key
@@ -405,6 +422,7 @@ class IndexTest < Test::Unit::TestCase
405
422
  assert_equal(2, index.size)
406
423
  assert_equal("two", index[0][:val])
407
424
  assert_equal("four", index[1][:val])
425
+ index.close
408
426
  end
409
427
 
410
428
  def test_index_multi_key
@@ -427,5 +445,24 @@ class IndexTest < Test::Unit::TestCase
427
445
  assert_equal("second floor", index[1][:location])
428
446
  assert_equal("backpack", index[3][:product])
429
447
  assert_equal("first floor", index[2][:location])
448
+ index.close
449
+ end
450
+
451
+ def test_auto_flush
452
+ fs_path = File.expand_path(File.join(File.dirname(__FILE__), '../../temp/fsdir'))
453
+ Dir[File.join(fs_path, "*")].each {|path| begin File.delete(path) rescue nil end}
454
+ data = %q(one two three four five six seven eight nine ten eleven twelve)
455
+ index1 = Index.new(:path => fs_path, :auto_flush => true)
456
+ index2 = Index.new(:path => fs_path, :auto_flush => true)
457
+ begin
458
+ data.each do |doc|
459
+ index1 << doc
460
+ index2 << doc
461
+ end
462
+ rescue Exception => e
463
+ assert(false, "This should not cause an error when auto flush has been set")
464
+ end
465
+ index1.close
466
+ index2.close
430
467
  end
431
468
  end