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

« back to all changes in this revision

Viewing changes to lucene/backwards/src/test/org/apache/lucene/search/TestCachingWrapperFilter.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.search;
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.IOException;
21
 
 
22
 
import org.apache.lucene.document.Document;
23
 
import org.apache.lucene.document.Field;
24
 
import org.apache.lucene.analysis.MockAnalyzer;
25
 
import org.apache.lucene.index.IndexReader;
26
 
import org.apache.lucene.index.RandomIndexWriter;
27
 
import org.apache.lucene.index.SerialMergeScheduler;
28
 
import org.apache.lucene.index.Term;
29
 
import org.apache.lucene.store.Directory;
30
 
import org.apache.lucene.util.LuceneTestCase;
31
 
import org.apache.lucene.util.FixedBitSet;
32
 
import org.apache.lucene.util._TestUtil;
33
 
 
34
 
public class TestCachingWrapperFilter extends LuceneTestCase {
35
 
 
36
 
  public void testCachingWorks() throws Exception {
37
 
    Directory dir = newDirectory();
38
 
    RandomIndexWriter writer = new RandomIndexWriter(random, dir);
39
 
    writer.close();
40
 
 
41
 
    IndexReader reader = IndexReader.open(dir, true);
42
 
 
43
 
    MockFilter filter = new MockFilter();
44
 
    CachingWrapperFilter cacher = new CachingWrapperFilter(filter);
45
 
 
46
 
    // first time, nested filter is called
47
 
    cacher.getDocIdSet(reader);
48
 
    assertTrue("first time", filter.wasCalled());
49
 
 
50
 
    // make sure no exception if cache is holding the wrong docIdSet
51
 
    cacher.getDocIdSet(reader);
52
 
 
53
 
    // second time, nested filter should not be called
54
 
    filter.clear();
55
 
    cacher.getDocIdSet(reader);
56
 
    assertFalse("second time", filter.wasCalled());
57
 
 
58
 
    reader.close();
59
 
    dir.close();
60
 
  }
61
 
  
62
 
  public void testNullDocIdSet() throws Exception {
63
 
    Directory dir = newDirectory();
64
 
    RandomIndexWriter writer = new RandomIndexWriter(random, dir);
65
 
    writer.close();
66
 
 
67
 
    IndexReader reader = IndexReader.open(dir, true);
68
 
 
69
 
    final Filter filter = new Filter() {
70
 
      @Override
71
 
      public DocIdSet getDocIdSet(IndexReader reader) {
72
 
        return null;
73
 
      }
74
 
    };
75
 
    CachingWrapperFilter cacher = new CachingWrapperFilter(filter);
76
 
 
77
 
    // the caching filter should return the empty set constant
78
 
    assertSame(DocIdSet.EMPTY_DOCIDSET, cacher.getDocIdSet(reader));
79
 
    
80
 
    reader.close();
81
 
    dir.close();
82
 
  }
83
 
  
84
 
  public void testNullDocIdSetIterator() throws Exception {
85
 
    Directory dir = newDirectory();
86
 
    RandomIndexWriter writer = new RandomIndexWriter(random, dir);
87
 
    writer.close();
88
 
 
89
 
    IndexReader reader = IndexReader.open(dir, true);
90
 
 
91
 
    final Filter filter = new Filter() {
92
 
      @Override
93
 
      public DocIdSet getDocIdSet(IndexReader reader) {
94
 
        return new DocIdSet() {
95
 
          @Override
96
 
          public DocIdSetIterator iterator() {
97
 
            return null;
98
 
          }
99
 
        };
100
 
      }
101
 
    };
102
 
    CachingWrapperFilter cacher = new CachingWrapperFilter(filter);
103
 
 
104
 
    // the caching filter should return the empty set constant
105
 
    assertSame(DocIdSet.EMPTY_DOCIDSET, cacher.getDocIdSet(reader));
106
 
    
107
 
    reader.close();
108
 
    dir.close();
109
 
  }
110
 
  
111
 
  private static void assertDocIdSetCacheable(IndexReader reader, Filter filter, boolean shouldCacheable) throws IOException {
112
 
    final CachingWrapperFilter cacher = new CachingWrapperFilter(filter);
113
 
    final DocIdSet originalSet = filter.getDocIdSet(reader.getSequentialSubReaders()[0]);
114
 
    final DocIdSet cachedSet = cacher.getDocIdSet(reader.getSequentialSubReaders()[0]);
115
 
    assertTrue(cachedSet.isCacheable());
116
 
    assertEquals(shouldCacheable, originalSet.isCacheable());
117
 
    //System.out.println("Original: "+originalSet.getClass().getName()+" -- cached: "+cachedSet.getClass().getName());
118
 
    if (originalSet.isCacheable()) {
119
 
      assertEquals("Cached DocIdSet must be of same class like uncached, if cacheable", originalSet.getClass(), cachedSet.getClass());
120
 
    } else {
121
 
      assertTrue("Cached DocIdSet must be an FixedBitSet if the original one was not cacheable (got " + cachedSet + ")", cachedSet instanceof FixedBitSet || cachedSet == DocIdSet.EMPTY_DOCIDSET);
122
 
    }
123
 
  }
124
 
  
125
 
  public void testIsCacheAble() throws Exception {
126
 
    Directory dir = newDirectory();
127
 
    RandomIndexWriter writer = new RandomIndexWriter(random, dir);
128
 
    writer.addDocument(new Document());
129
 
    writer.close();
130
 
 
131
 
    IndexReader reader = IndexReader.open(dir, true);
132
 
 
133
 
    // not cacheable:
134
 
    assertDocIdSetCacheable(reader, new QueryWrapperFilter(new TermQuery(new Term("test","value"))), false);
135
 
    // returns default empty docidset, always cacheable:
136
 
    assertDocIdSetCacheable(reader, NumericRangeFilter.newIntRange("test", Integer.valueOf(10000), Integer.valueOf(-10000), true, true), true);
137
 
    // is cacheable:
138
 
    assertDocIdSetCacheable(reader, FieldCacheRangeFilter.newIntRange("test", Integer.valueOf(10), Integer.valueOf(20), true, true), true);
139
 
    // a fixedbitset filter is always cacheable
140
 
    assertDocIdSetCacheable(reader, new Filter() {
141
 
      @Override
142
 
      public DocIdSet getDocIdSet(IndexReader reader) {
143
 
        return new FixedBitSet(reader.maxDoc());
144
 
      }
145
 
    }, true);
146
 
 
147
 
    reader.close();
148
 
    dir.close();
149
 
  }
150
 
 
151
 
  public void testEnforceDeletions() throws Exception {
152
 
    Directory dir = newDirectory();
153
 
    RandomIndexWriter writer = new RandomIndexWriter(
154
 
        random,
155
 
        dir,
156
 
        newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).
157
 
            setMergeScheduler(new SerialMergeScheduler()).
158
 
            // asserts below requires no unexpected merges:
159
 
            setMergePolicy(newLogMergePolicy(10))
160
 
    );
161
 
 
162
 
    // NOTE: cannot use writer.getReader because RIW (on
163
 
    // flipping a coin) may give us a newly opened reader,
164
 
    // but we use .reopen on this reader below and expect to
165
 
    // (must) get an NRT reader:
166
 
    IndexReader reader = IndexReader.open(writer.w, true);
167
 
    // same reason we don't wrap?
168
 
    IndexSearcher searcher = newSearcher(reader, false);
169
 
 
170
 
    // add a doc, refresh the reader, and check that its there
171
 
    Document doc = new Document();
172
 
    doc.add(newField("id", "1", Field.Store.YES, Field.Index.NOT_ANALYZED));
173
 
    writer.addDocument(doc);
174
 
 
175
 
    reader = refreshReader(reader);
176
 
    searcher.close();
177
 
    searcher = newSearcher(reader, false);
178
 
 
179
 
    TopDocs docs = searcher.search(new MatchAllDocsQuery(), 1);
180
 
    assertEquals("Should find a hit...", 1, docs.totalHits);
181
 
 
182
 
    final Filter startFilter = new QueryWrapperFilter(new TermQuery(new Term("id", "1")));
183
 
 
184
 
    // ignore deletions
185
 
    CachingWrapperFilter filter = new CachingWrapperFilter(startFilter, CachingWrapperFilter.DeletesMode.IGNORE);
186
 
        
187
 
    docs = searcher.search(new MatchAllDocsQuery(), filter, 1);
188
 
    assertEquals("[query + filter] Should find a hit...", 1, docs.totalHits);
189
 
    ConstantScoreQuery constantScore = new ConstantScoreQuery(filter);
190
 
    docs = searcher.search(constantScore, 1);
191
 
    assertEquals("[just filter] Should find a hit...", 1, docs.totalHits);
192
 
 
193
 
    // now delete the doc, refresh the reader, and see that it's not there
194
 
    _TestUtil.keepFullyDeletedSegments(writer.w);
195
 
    writer.deleteDocuments(new Term("id", "1"));
196
 
 
197
 
    reader = refreshReader(reader);
198
 
    searcher.close();
199
 
    searcher = newSearcher(reader, false);
200
 
 
201
 
    docs = searcher.search(new MatchAllDocsQuery(), filter, 1);
202
 
    assertEquals("[query + filter] Should *not* find a hit...", 0, docs.totalHits);
203
 
 
204
 
    docs = searcher.search(constantScore, 1);
205
 
    assertEquals("[just filter] Should find a hit...", 1, docs.totalHits);
206
 
 
207
 
 
208
 
    // force cache to regenerate:
209
 
    filter = new CachingWrapperFilter(startFilter, CachingWrapperFilter.DeletesMode.RECACHE);
210
 
 
211
 
    writer.addDocument(doc);
212
 
 
213
 
    reader = refreshReader(reader);
214
 
    searcher.close();
215
 
    searcher = newSearcher(reader, false);
216
 
        
217
 
    docs = searcher.search(new MatchAllDocsQuery(), filter, 1);
218
 
 
219
 
    assertEquals("[query + filter] Should find a hit...", 1, docs.totalHits);
220
 
 
221
 
    constantScore = new ConstantScoreQuery(filter);
222
 
    docs = searcher.search(constantScore, 1);
223
 
    assertEquals("[just filter] Should find a hit...", 1, docs.totalHits);
224
 
 
225
 
    // NOTE: important to hold ref here so GC doesn't clear
226
 
    // the cache entry!  Else the assert below may sometimes
227
 
    // fail:
228
 
    IndexReader oldReader = reader;
229
 
 
230
 
    // make sure we get a cache hit when we reopen reader
231
 
    // that had no change to deletions
232
 
    // Deletes nothing:
233
 
    writer.deleteDocuments(new Term("foo", "bar"));
234
 
    reader = refreshReader(reader);
235
 
    assertTrue(reader == oldReader);
236
 
    int missCount = filter.missCount;
237
 
    docs = searcher.search(constantScore, 1);
238
 
    assertEquals("[just filter] Should find a hit...", 1, docs.totalHits);
239
 
    assertEquals(missCount, filter.missCount);
240
 
 
241
 
    // now delete the doc, refresh the reader, and see that it's not there
242
 
    writer.deleteDocuments(new Term("id", "1"));
243
 
 
244
 
    reader = refreshReader(reader);
245
 
    searcher.close();
246
 
    searcher = newSearcher(reader, false);
247
 
 
248
 
    missCount = filter.missCount;
249
 
    docs = searcher.search(new MatchAllDocsQuery(), filter, 1);
250
 
    assertEquals(missCount+1, filter.missCount);
251
 
    assertEquals("[query + filter] Should *not* find a hit...", 0, docs.totalHits);
252
 
    docs = searcher.search(constantScore, 1);
253
 
    assertEquals("[just filter] Should *not* find a hit...", 0, docs.totalHits);
254
 
 
255
 
 
256
 
    // apply deletions dynamically
257
 
    filter = new CachingWrapperFilter(startFilter, CachingWrapperFilter.DeletesMode.DYNAMIC);
258
 
 
259
 
    writer.addDocument(doc);
260
 
    reader = refreshReader(reader);
261
 
    searcher.close();
262
 
    searcher = newSearcher(reader, false);
263
 
        
264
 
    docs = searcher.search(new MatchAllDocsQuery(), filter, 1);
265
 
    assertEquals("[query + filter] Should find a hit...", 1, docs.totalHits);
266
 
    constantScore = new ConstantScoreQuery(filter);
267
 
    docs = searcher.search(constantScore, 1);
268
 
    assertEquals("[just filter] Should find a hit...", 1, docs.totalHits);
269
 
 
270
 
    // now delete the doc, refresh the reader, and see that it's not there
271
 
    writer.deleteDocuments(new Term("id", "1"));
272
 
 
273
 
    reader = refreshReader(reader);
274
 
    searcher.close();
275
 
    searcher = newSearcher(reader, false);
276
 
 
277
 
    docs = searcher.search(new MatchAllDocsQuery(), filter, 1);
278
 
    assertEquals("[query + filter] Should *not* find a hit...", 0, docs.totalHits);
279
 
 
280
 
    missCount = filter.missCount;
281
 
    docs = searcher.search(constantScore, 1);
282
 
    assertEquals("[just filter] Should *not* find a hit...", 0, docs.totalHits);
283
 
 
284
 
    // doesn't count as a miss
285
 
    assertEquals(missCount, filter.missCount);
286
 
 
287
 
    // NOTE: silliness to make sure JRE does not optimize
288
 
    // away our holding onto oldReader to prevent
289
 
    // CachingWrapperFilter's WeakHashMap from dropping the
290
 
    // entry:
291
 
    assertTrue(oldReader != null);
292
 
 
293
 
    searcher.close();
294
 
    reader.close();
295
 
    writer.close();
296
 
    dir.close();
297
 
  }
298
 
 
299
 
  private static IndexReader refreshReader(IndexReader reader) throws IOException {
300
 
    IndexReader oldReader = reader;
301
 
    reader = reader.reopen();
302
 
    if (reader != oldReader) {
303
 
      oldReader.close();
304
 
    }
305
 
    return reader;
306
 
  }
307
 
}