~slub.team/goobi-indexserver/3.x

« back to all changes in this revision

Viewing changes to lucene/backwards/src/test-framework/org/apache/lucene/index/RandomIndexWriter.java

  • Committer: Sebastian Meyer
  • Date: 2012-08-03 09:12:40 UTC
  • Revision ID: sebastian.meyer@slub-dresden.de-20120803091240-x6861b0vabq1xror
Remove Lucene and Solr source code and add patches instead
Fix Bug #985487: Auto-suggestion for the search interface

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
package org.apache.lucene.index;
2
 
 
3
 
/**
4
 
 * Licensed to the Apache Software Foundation (ASF) under one or more
5
 
 * contributor license agreements.  See the NOTICE file distributed with
6
 
 * this work for additional information regarding copyright ownership.
7
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
8
 
 * (the "License"); you may not use this file except in compliance with
9
 
 * the License.  You may obtain a copy of the License at
10
 
 *
11
 
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 
 *
13
 
 * Unless required by applicable law or agreed to in writing, software
14
 
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 
 * See the License for the specific language governing permissions and
17
 
 * limitations under the License.
18
 
 */
19
 
 
20
 
import java.io.Closeable;
21
 
import java.io.IOException;
22
 
import java.util.Collection;
23
 
import java.util.Collections;
24
 
import java.util.Random;
25
 
 
26
 
import org.apache.lucene.analysis.Analyzer;
27
 
import org.apache.lucene.analysis.MockAnalyzer;
28
 
import org.apache.lucene.document.Document;
29
 
import org.apache.lucene.index.IndexWriter; // javadoc
30
 
import org.apache.lucene.search.Query;
31
 
import org.apache.lucene.store.Directory;
32
 
import org.apache.lucene.util.LuceneTestCase;
33
 
import org.apache.lucene.util.Version;
34
 
import org.apache.lucene.util._TestUtil;
35
 
 
36
 
/** Silly class that randomizes the indexing experience.  EG
37
 
 *  it may swap in a different merge policy/scheduler; may
38
 
 *  commit periodically; may or may not optimize in the end,
39
 
 *  may flush by doc count instead of RAM, etc. 
40
 
 */
41
 
 
42
 
public class RandomIndexWriter implements Closeable {
43
 
 
44
 
  public IndexWriter w;
45
 
  private final Random r;
46
 
  int docCount;
47
 
  int flushAt;
48
 
  private double flushAtFactor = 1.0;
49
 
  private boolean getReaderCalled;
50
 
 
51
 
  // Randomly calls Thread.yield so we mixup thread scheduling
52
 
  private static final class MockIndexWriter extends IndexWriter {
53
 
 
54
 
    private final Random r;
55
 
 
56
 
    public MockIndexWriter(Random r,Directory dir, IndexWriterConfig conf) throws IOException {
57
 
      super(dir, conf);
58
 
      // must make a private random since our methods are
59
 
      // called from different threads; else test failures may
60
 
      // not be reproducible from the original seed
61
 
      this.r = new Random(r.nextInt());
62
 
    }
63
 
 
64
 
    @Override
65
 
    boolean testPoint(String name) {
66
 
      if (r.nextInt(4) == 2)
67
 
        Thread.yield();
68
 
      return true;
69
 
    }
70
 
  }
71
 
 
72
 
  /** create a RandomIndexWriter with a random config: Uses TEST_VERSION_CURRENT and Whitespace+LowercasingAnalyzer */
73
 
  public RandomIndexWriter(Random r, Directory dir) throws IOException {
74
 
    this(r, dir, LuceneTestCase.newIndexWriterConfig(r, LuceneTestCase.TEST_VERSION_CURRENT, new MockAnalyzer(r)));
75
 
  }
76
 
  
77
 
  /** create a RandomIndexWriter with a random config: Uses TEST_VERSION_CURRENT */
78
 
  public RandomIndexWriter(Random r, Directory dir, Analyzer a) throws IOException {
79
 
    this(r, dir, LuceneTestCase.newIndexWriterConfig(r, LuceneTestCase.TEST_VERSION_CURRENT, a));
80
 
  }
81
 
  
82
 
  /** create a RandomIndexWriter with a random config */
83
 
  public RandomIndexWriter(Random r, Directory dir, Version v, Analyzer a) throws IOException {
84
 
    this(r, dir, LuceneTestCase.newIndexWriterConfig(r, v, a));
85
 
  }
86
 
  
87
 
  /** create a RandomIndexWriter with the provided config */
88
 
  public RandomIndexWriter(Random r, Directory dir, IndexWriterConfig c) throws IOException {
89
 
    this.r = r;
90
 
    w = new MockIndexWriter(r, dir, c);
91
 
    flushAt = _TestUtil.nextInt(r, 10, 1000);
92
 
    if (LuceneTestCase.VERBOSE) {
93
 
      System.out.println("RIW config=" + w.getConfig());
94
 
    }
95
 
  } 
96
 
 
97
 
  /**
98
 
   * Adds a Document.
99
 
   * @see IndexWriter#addDocument(Document)
100
 
   */
101
 
  public void addDocument(final Document doc) throws IOException {
102
 
    if (r.nextInt(5) == 3) {
103
 
      // TODO: maybe, we should simply buffer up added docs
104
 
      // (but we need to clone them), and only when
105
 
      // getReader, commit, etc. are called, we do an
106
 
      // addDocuments?  Would be better testing.
107
 
      w.addDocuments(Collections.singletonList(doc));
108
 
    } else {
109
 
      w.addDocument(doc);
110
 
    }
111
 
    maybeCommit();
112
 
  }
113
 
  
114
 
  public void addDocuments(Collection<Document> docs) throws IOException {
115
 
    w.addDocuments(docs);
116
 
    maybeCommit();
117
 
  }
118
 
 
119
 
  public void updateDocuments(Term delTerm, Collection<Document> docs) throws IOException {
120
 
    w.updateDocuments(delTerm, docs);
121
 
    maybeCommit();
122
 
  }
123
 
 
124
 
  private void maybeCommit() throws IOException {
125
 
    if (docCount++ == flushAt) {
126
 
      if (LuceneTestCase.VERBOSE) {
127
 
        System.out.println("RIW.add/updateDocument: now doing a commit at docCount=" + docCount);
128
 
      }
129
 
      w.commit();
130
 
      flushAt += _TestUtil.nextInt(r, (int) (flushAtFactor * 10), (int) (flushAtFactor * 1000));
131
 
      if (flushAtFactor < 2e6) {
132
 
        // gradually but exponentially increase time b/w flushes
133
 
        flushAtFactor *= 1.05;
134
 
      }
135
 
    }
136
 
  }
137
 
 
138
 
  /**
139
 
   * Updates a document.
140
 
   * @see IndexWriter#updateDocument(Term, Document)
141
 
   */
142
 
  public void updateDocument(Term t, final Document doc) throws IOException {
143
 
    if (r.nextInt(5) == 3) {
144
 
      w.updateDocuments(t, Collections.singletonList(doc));
145
 
    } else {
146
 
      w.updateDocument(t, doc);
147
 
    }
148
 
    maybeCommit();
149
 
  }
150
 
  
151
 
  public void addIndexes(Directory... dirs) throws CorruptIndexException, IOException {
152
 
    w.addIndexes(dirs);
153
 
  }
154
 
  
155
 
  public void deleteDocuments(Term term) throws CorruptIndexException, IOException {
156
 
    w.deleteDocuments(term);
157
 
  }
158
 
 
159
 
  public void deleteDocuments(Query q) throws CorruptIndexException, IOException {
160
 
    w.deleteDocuments(q);
161
 
  }
162
 
  
163
 
  public void commit() throws CorruptIndexException, IOException {
164
 
    w.commit();
165
 
  }
166
 
  
167
 
  public int numDocs() throws IOException {
168
 
    return w.numDocs();
169
 
  }
170
 
 
171
 
  public int maxDoc() {
172
 
    return w.maxDoc();
173
 
  }
174
 
 
175
 
  public void deleteAll() throws IOException {
176
 
    w.deleteAll();
177
 
  }
178
 
 
179
 
  private boolean doRandomOptimize = true;
180
 
  private boolean doRandomOptimizeAssert = true;
181
 
 
182
 
  public void setDoRandomOptimize(boolean v) {
183
 
    doRandomOptimize = v;
184
 
  }
185
 
 
186
 
  public void setDoRandomOptimizeAssert(boolean v) {
187
 
    doRandomOptimizeAssert = v;
188
 
  }
189
 
 
190
 
  private void doRandomOptimize() throws IOException {
191
 
    if (doRandomOptimize) {
192
 
      final int segCount = w.getSegmentCount();
193
 
      if (r.nextBoolean() || segCount == 0) {
194
 
        // full optimize
195
 
        w.optimize();
196
 
      } else {
197
 
        // partial optimize
198
 
        final int limit = _TestUtil.nextInt(r, 1, segCount);
199
 
        w.optimize(limit);
200
 
        assert !doRandomOptimizeAssert || w.getSegmentCount() <= limit: "limit=" + limit + " actual=" + w.getSegmentCount();
201
 
      }
202
 
    }
203
 
  }
204
 
 
205
 
  public IndexReader getReader() throws IOException {
206
 
    return getReader(true);
207
 
  }
208
 
 
209
 
  public IndexReader getReader(boolean applyDeletions) throws IOException {
210
 
    getReaderCalled = true;
211
 
    if (r.nextInt(4) == 2) {
212
 
      doRandomOptimize();
213
 
    }
214
 
    if (r.nextBoolean()) {
215
 
      if (LuceneTestCase.VERBOSE) {
216
 
        System.out.println("RIW.getReader: use NRT reader");
217
 
      }
218
 
      if (r.nextInt(5) == 1) {
219
 
        w.commit();
220
 
      }
221
 
      return w.getReader(applyDeletions);
222
 
    } else {
223
 
      if (LuceneTestCase.VERBOSE) {
224
 
        System.out.println("RIW.getReader: open new reader");
225
 
      }
226
 
      w.commit();
227
 
      if (r.nextBoolean()) {
228
 
        return IndexReader.open(w.getDirectory(), new KeepOnlyLastCommitDeletionPolicy(), r.nextBoolean(), _TestUtil.nextInt(r, 1, 10));
229
 
      } else {
230
 
        return w.getReader(applyDeletions);
231
 
      }
232
 
    }
233
 
  }
234
 
 
235
 
  /**
236
 
   * Close this writer.
237
 
   * @see IndexWriter#close()
238
 
   */
239
 
  public void close() throws IOException {
240
 
    // if someone isn't using getReader() API, we want to be sure to
241
 
    // maybeOptimize since presumably they might open a reader on the dir.
242
 
    if (getReaderCalled == false && r.nextInt(8) == 2) {
243
 
      doRandomOptimize();
244
 
    }
245
 
    w.close();
246
 
  }
247
 
 
248
 
  /**
249
 
   * Forces an optimize.
250
 
   * <p>
251
 
   * NOTE: this should be avoided in tests unless absolutely necessary,
252
 
   * as it will result in less test coverage.
253
 
   * @see IndexWriter#optimize()
254
 
   */
255
 
  public void optimize() throws IOException {
256
 
    w.optimize();
257
 
  }
258
 
}