LUCENE-4211: add AssertingReader/Codec

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1361243 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Muir 2012-07-13 14:45:19 +00:00
parent 7993e39d38
commit 9c9039582e
14 changed files with 773 additions and 1 deletions

View File

@ -55,6 +55,7 @@ public final class MultiDocsAndPositionsEnum extends DocsAndPositionsEnum {
this.subs[i].slice = subs[i].slice;
}
upto = -1;
doc = -1;
current = null;
return this;
}
@ -69,6 +70,7 @@ public final class MultiDocsAndPositionsEnum extends DocsAndPositionsEnum {
@Override
public int freq() throws IOException {
assert current != null;
return current.freq();
}

View File

@ -52,6 +52,7 @@ public final class MultiDocsEnum extends DocsEnum {
this.subs[i].slice = subs[i].slice;
}
upto = -1;
doc = -1;
current = null;
return this;
}

View File

@ -37,6 +37,7 @@ import org.apache.lucene.index.Fields;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.util.ArrayUtil;
import org.apache.lucene.util.BytesRef;
@ -128,6 +129,8 @@ public class TokenSources {
if (termsEnum.next() != null) {
DocsAndPositionsEnum dpEnum = termsEnum.docsAndPositions(null, null, false);
if (dpEnum != null) {
int doc = dpEnum.nextDoc();
assert doc >= 0 && doc != DocIdSetIterator.NO_MORE_DOCS;
int pos = dpEnum.nextPosition();
if (pos >= 0) {
return true;

View File

@ -0,0 +1,94 @@
package org.apache.lucene.codecs.asserting;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.codecs.Codec;
import org.apache.lucene.codecs.DocValuesFormat;
import org.apache.lucene.codecs.FieldInfosFormat;
import org.apache.lucene.codecs.LiveDocsFormat;
import org.apache.lucene.codecs.NormsFormat;
import org.apache.lucene.codecs.PostingsFormat;
import org.apache.lucene.codecs.SegmentInfoFormat;
import org.apache.lucene.codecs.StoredFieldsFormat;
import org.apache.lucene.codecs.TermVectorsFormat;
import org.apache.lucene.codecs.lucene40.Lucene40Codec; // javadocs @link
import org.apache.lucene.codecs.lucene40.Lucene40DocValuesFormat;
import org.apache.lucene.codecs.lucene40.Lucene40FieldInfosFormat;
import org.apache.lucene.codecs.lucene40.Lucene40LiveDocsFormat;
import org.apache.lucene.codecs.lucene40.Lucene40NormsFormat;
import org.apache.lucene.codecs.lucene40.Lucene40SegmentInfoFormat;
import org.apache.lucene.codecs.lucene40.Lucene40StoredFieldsFormat;
/**
* Acts like {@link Lucene40Codec} but with additional asserts.
*/
public class AssertingCodec extends Codec {
private final PostingsFormat postings = new AssertingPostingsFormat();
private final SegmentInfoFormat infos = new Lucene40SegmentInfoFormat();
private final StoredFieldsFormat fields = new Lucene40StoredFieldsFormat();
private final FieldInfosFormat fieldInfos = new Lucene40FieldInfosFormat();
private final TermVectorsFormat vectors = new AssertingTermVectorsFormat();
private final DocValuesFormat docValues = new Lucene40DocValuesFormat();
private final NormsFormat norms = new Lucene40NormsFormat();
private final LiveDocsFormat liveDocs = new Lucene40LiveDocsFormat();
public AssertingCodec() {
super("Asserting");
}
@Override
public PostingsFormat postingsFormat() {
return postings;
}
@Override
public DocValuesFormat docValuesFormat() {
return docValues;
}
@Override
public StoredFieldsFormat storedFieldsFormat() {
return fields;
}
@Override
public TermVectorsFormat termVectorsFormat() {
return vectors;
}
@Override
public FieldInfosFormat fieldInfosFormat() {
return fieldInfos;
}
@Override
public SegmentInfoFormat segmentInfoFormat() {
return infos;
}
@Override
public NormsFormat normsFormat() {
return norms;
}
@Override
public LiveDocsFormat liveDocsFormat() {
return liveDocs;
}
}

View File

@ -0,0 +1,88 @@
package org.apache.lucene.codecs.asserting;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import org.apache.lucene.codecs.FieldsConsumer;
import org.apache.lucene.codecs.FieldsProducer;
import org.apache.lucene.codecs.PostingsFormat;
import org.apache.lucene.codecs.lucene40.Lucene40PostingsFormat;
import org.apache.lucene.index.AssertingAtomicReader;
import org.apache.lucene.index.FieldsEnum;
import org.apache.lucene.index.SegmentReadState;
import org.apache.lucene.index.SegmentWriteState;
import org.apache.lucene.index.Terms;
/**
* Just like {@link Lucene40PostingsFormat} but with additional asserts.
*/
public class AssertingPostingsFormat extends PostingsFormat {
private final PostingsFormat in = new Lucene40PostingsFormat();
public AssertingPostingsFormat() {
super("Asserting");
}
// TODO: we could add some useful checks here?
@Override
public FieldsConsumer fieldsConsumer(SegmentWriteState state) throws IOException {
return in.fieldsConsumer(state);
}
@Override
public FieldsProducer fieldsProducer(SegmentReadState state) throws IOException {
return new AssertingFieldsProducer(in.fieldsProducer(state));
}
static class AssertingFieldsProducer extends FieldsProducer {
private final FieldsProducer in;
AssertingFieldsProducer(FieldsProducer in) {
this.in = in;
}
@Override
public void close() throws IOException {
in.close();
}
@Override
public FieldsEnum iterator() throws IOException {
FieldsEnum iterator = in.iterator();
assert iterator != null;
return new AssertingAtomicReader.AssertingFieldsEnum(iterator);
}
@Override
public Terms terms(String field) throws IOException {
Terms terms = in.terms(field);
return terms == null ? null : new AssertingAtomicReader.AssertingTerms(terms);
}
@Override
public int size() throws IOException {
return in.size();
}
@Override
public long getUniqueTermCount() throws IOException {
return in.getUniqueTermCount();
}
}
}

View File

@ -0,0 +1,72 @@
package org.apache.lucene.codecs.asserting;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import org.apache.lucene.codecs.TermVectorsFormat;
import org.apache.lucene.codecs.TermVectorsReader;
import org.apache.lucene.codecs.TermVectorsWriter;
import org.apache.lucene.codecs.lucene40.Lucene40TermVectorsFormat;
import org.apache.lucene.index.AssertingAtomicReader;
import org.apache.lucene.index.FieldInfos;
import org.apache.lucene.index.Fields;
import org.apache.lucene.index.SegmentInfo;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.IOContext;
/**
* Just like {@link Lucene40TermVectorsFormat} but with additional asserts.
*/
public class AssertingTermVectorsFormat extends TermVectorsFormat {
private final TermVectorsFormat in = new Lucene40TermVectorsFormat();
@Override
public TermVectorsReader vectorsReader(Directory directory, SegmentInfo segmentInfo, FieldInfos fieldInfos, IOContext context) throws IOException {
return new AssertingTermVectorsReader(in.vectorsReader(directory, segmentInfo, fieldInfos, context));
}
@Override
public TermVectorsWriter vectorsWriter(Directory directory, SegmentInfo segmentInfo, IOContext context) throws IOException {
return in.vectorsWriter(directory, segmentInfo, context);
}
static class AssertingTermVectorsReader extends TermVectorsReader {
private final TermVectorsReader in;
AssertingTermVectorsReader(TermVectorsReader in) {
this.in = in;
}
@Override
public void close() throws IOException {
in.close();
}
@Override
public Fields get(int doc) throws IOException {
Fields fields = in.get(doc);
return fields == null ? null : new AssertingAtomicReader.AssertingFields(fields);
}
@Override
public TermVectorsReader clone() {
return new AssertingTermVectorsReader(in.clone());
}
}
}

View File

@ -0,0 +1,25 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
Codec for testing that asserts various contracts of the codec apis.
</body>
</html>

View File

@ -0,0 +1,379 @@
package org.apache.lucene.index;
import java.io.IOException;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.automaton.CompiledAutomaton;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* A {@link FilterAtomicReader} that can be used to apply
* additional checks for tests.
*/
public class AssertingAtomicReader extends FilterAtomicReader {
public AssertingAtomicReader(AtomicReader in) {
super(in);
// check some basic reader sanity
assert in.maxDoc() >= 0;
assert in.numDocs() <= in.maxDoc();
assert in.numDeletedDocs() + in.numDocs() == in.maxDoc();
assert !in.hasDeletions() || in.numDeletedDocs() > 0 && in.numDocs() < in.maxDoc();
}
@Override
public Fields fields() throws IOException {
Fields fields = super.fields();
return fields == null ? null : new AssertingFields(fields);
}
@Override
public Fields getTermVectors(int docID) throws IOException {
Fields fields = super.getTermVectors(docID);
return fields == null ? null : new AssertingFields(fields);
}
/**
* Wraps a Fields but with additional asserts
*/
public static class AssertingFields extends FilterFields {
public AssertingFields(Fields in) {
super(in);
}
@Override
public FieldsEnum iterator() throws IOException {
FieldsEnum fieldsEnum = super.iterator();
assert fieldsEnum != null;
return new AssertingFieldsEnum(fieldsEnum);
}
@Override
public Terms terms(String field) throws IOException {
Terms terms = super.terms(field);
return terms == null ? null : new AssertingTerms(terms);
}
}
/**
* Wraps a FieldsEnum but with additional asserts
*/
public static class AssertingFieldsEnum extends FilterFieldsEnum {
public AssertingFieldsEnum(FieldsEnum in) {
super(in);
}
@Override
public Terms terms() throws IOException {
Terms terms = super.terms();
return terms == null ? null : new AssertingTerms(terms);
}
}
/**
* Wraps a Terms but with additional asserts
*/
public static class AssertingTerms extends FilterTerms {
public AssertingTerms(Terms in) {
super(in);
}
@Override
public TermsEnum intersect(CompiledAutomaton automaton, BytesRef bytes) throws IOException {
TermsEnum termsEnum = super.intersect(automaton, bytes);
assert termsEnum != null;
return new AssertingTermsEnum(termsEnum);
}
@Override
public TermsEnum iterator(TermsEnum reuse) throws IOException {
// TODO: should we give this thing a random to be super-evil,
// and randomly *not* unwrap?
if (reuse instanceof AssertingTermsEnum) {
reuse = ((AssertingTermsEnum) reuse).in;
}
TermsEnum termsEnum = super.iterator(reuse);
assert termsEnum != null;
return new AssertingTermsEnum(termsEnum);
}
}
static class AssertingTermsEnum extends FilterTermsEnum {
private enum State {INITIAL, POSITIONED, UNPOSITIONED};
private State state = State.INITIAL;
public AssertingTermsEnum(TermsEnum in) {
super(in);
}
@Override
public DocsEnum docs(Bits liveDocs, DocsEnum reuse, boolean needsFreqs) throws IOException {
assert state == State.POSITIONED: "docs(...) called on unpositioned TermsEnum";
// TODO: should we give this thing a random to be super-evil,
// and randomly *not* unwrap?
if (reuse instanceof AssertingDocsEnum) {
reuse = ((AssertingDocsEnum) reuse).in;
}
DocsEnum docs = super.docs(liveDocs, reuse, needsFreqs);
return docs == null ? null : new AssertingDocsEnum(docs);
}
@Override
public DocsAndPositionsEnum docsAndPositions(Bits liveDocs, DocsAndPositionsEnum reuse, boolean needsOffsets) throws IOException {
assert state == State.POSITIONED: "docsAndPositions(...) called on unpositioned TermsEnum";
// TODO: should we give this thing a random to be super-evil,
// and randomly *not* unwrap?
if (reuse instanceof AssertingDocsAndPositionsEnum) {
reuse = ((AssertingDocsAndPositionsEnum) reuse).in;
}
DocsAndPositionsEnum docs = super.docsAndPositions(liveDocs, reuse, needsOffsets);
return docs == null ? null : new AssertingDocsAndPositionsEnum(docs);
}
// TODO: we should separately track if we are 'at the end' ?
// someone should not call next() after it returns null!!!!
@Override
public BytesRef next() throws IOException {
assert state == State.INITIAL || state == State.POSITIONED: "next() called on unpositioned TermsEnum";
BytesRef result = super.next();
if (result == null) {
state = State.UNPOSITIONED;
} else {
state = State.POSITIONED;
}
return result;
}
@Override
public long ord() throws IOException {
assert state == State.POSITIONED : "ord() called on unpositioned TermsEnum";
return super.ord();
}
@Override
public int docFreq() throws IOException {
assert state == State.POSITIONED : "docFreq() called on unpositioned TermsEnum";
return super.docFreq();
}
@Override
public long totalTermFreq() throws IOException {
assert state == State.POSITIONED : "totalTermFreq() called on unpositioned TermsEnum";
return super.totalTermFreq();
}
@Override
public BytesRef term() throws IOException {
assert state == State.POSITIONED : "term() called on unpositioned TermsEnum";
return super.term();
}
@Override
public void seekExact(long ord) throws IOException {
super.seekExact(ord);
state = State.POSITIONED;
}
@Override
public SeekStatus seekCeil(BytesRef term, boolean useCache) throws IOException {
SeekStatus result = super.seekCeil(term, useCache);
if (result == SeekStatus.END) {
state = State.UNPOSITIONED;
} else {
state = State.POSITIONED;
}
return result;
}
@Override
public boolean seekExact(BytesRef text, boolean useCache) throws IOException {
if (super.seekExact(text, useCache)) {
state = State.POSITIONED;
return true;
} else {
state = State.UNPOSITIONED;
return false;
}
}
@Override
public TermState termState() throws IOException {
assert state == State.POSITIONED : "termState() called on unpositioned TermsEnum";
return super.termState();
}
@Override
public void seekExact(BytesRef term, TermState state) throws IOException {
super.seekExact(term, state);
this.state = State.POSITIONED;
}
}
static enum DocsEnumState { START, ITERATING, FINISHED };
static class AssertingDocsEnum extends FilterDocsEnum {
private DocsEnumState state = DocsEnumState.START;
public AssertingDocsEnum(DocsEnum in) {
super(in);
int docid = in.docID();
assert docid == -1 || docid == DocIdSetIterator.NO_MORE_DOCS : "invalid initial doc id: " + docid;
}
@Override
public int nextDoc() throws IOException {
assert state != DocsEnumState.FINISHED : "nextDoc() called after NO_MORE_DOCS";
int nextDoc = super.nextDoc();
assert nextDoc >= 0 : "invalid doc id: " + nextDoc;
if (nextDoc == DocIdSetIterator.NO_MORE_DOCS) {
state = DocsEnumState.FINISHED;
} else {
state = DocsEnumState.ITERATING;
}
return nextDoc;
}
@Override
public int advance(int target) throws IOException {
assert state != DocsEnumState.FINISHED : "advance() called after NO_MORE_DOCS";
int advanced = super.advance(target);
assert advanced >= 0 : "invalid doc id: " + advanced;
assert advanced >= target : "backwards advance from: " + target + " to: " + advanced;
if (advanced == DocIdSetIterator.NO_MORE_DOCS) {
state = DocsEnumState.FINISHED;
} else {
state = DocsEnumState.ITERATING;
}
return advanced;
}
// NOTE: We don't assert anything for docId(). Specifically DocsEnum javadocs
// are ambiguous with DocIdSetIterator here, DocIdSetIterator says its ok
// to call this method before nextDoc(), just that it must be -1 or NO_MORE_DOCS!
@Override
public int freq() throws IOException {
assert state != DocsEnumState.START : "freq() called before nextDoc()/advance()";
assert state != DocsEnumState.FINISHED : "freq() called after NO_MORE_DOCS";
int freq = super.freq();
assert freq > 0;
return freq;
}
}
static class AssertingDocsAndPositionsEnum extends FilterDocsAndPositionsEnum {
private DocsEnumState state = DocsEnumState.START;
private int positionMax = 0;
private int positionCount = 0;
public AssertingDocsAndPositionsEnum(DocsAndPositionsEnum in) {
super(in);
int docid = in.docID();
assert docid == -1 || docid == DocIdSetIterator.NO_MORE_DOCS : "invalid initial doc id: " + docid;
}
@Override
public int nextDoc() throws IOException {
assert state != DocsEnumState.FINISHED : "nextDoc() called after NO_MORE_DOCS";
int nextDoc = super.nextDoc();
assert nextDoc >= 0 : "invalid doc id: " + nextDoc;
positionCount = 0;
if (nextDoc == DocIdSetIterator.NO_MORE_DOCS) {
state = DocsEnumState.FINISHED;
positionMax = 0;
} else {
state = DocsEnumState.ITERATING;
positionMax = super.freq();
}
return nextDoc;
}
@Override
public int advance(int target) throws IOException {
assert state != DocsEnumState.FINISHED : "advance() called after NO_MORE_DOCS";
int advanced = super.advance(target);
assert advanced >= 0 : "invalid doc id: " + advanced;
assert advanced >= target : "backwards advance from: " + target + " to: " + advanced;
positionCount = 0;
if (advanced == DocIdSetIterator.NO_MORE_DOCS) {
state = DocsEnumState.FINISHED;
positionMax = 0;
} else {
state = DocsEnumState.ITERATING;
positionMax = super.freq();
}
return advanced;
}
@Override
public int freq() throws IOException {
assert state != DocsEnumState.START : "freq() called before nextDoc()/advance()";
assert state != DocsEnumState.FINISHED : "freq() called after NO_MORE_DOCS";
int freq = super.freq();
assert freq > 0;
return freq;
}
@Override
public int nextPosition() throws IOException {
assert state != DocsEnumState.START : "nextPosition() called before nextDoc()/advance()";
assert state != DocsEnumState.FINISHED : "nextPosition() called after NO_MORE_DOCS";
assert positionCount < positionMax : "nextPosition() called more than freq() times!";
int position = super.nextPosition();
assert position >= 0 || position == -1 : "invalid position: " + position;
positionCount++;
return position;
}
@Override
public int startOffset() throws IOException {
assert state != DocsEnumState.START : "startOffset() called before nextDoc()/advance()";
assert state != DocsEnumState.FINISHED : "startOffset() called after NO_MORE_DOCS";
assert positionCount > 0 : "startOffset() called before nextPosition()!";
return super.startOffset();
}
@Override
public int endOffset() throws IOException {
assert state != DocsEnumState.START : "endOffset() called before nextDoc()/advance()";
assert state != DocsEnumState.FINISHED : "endOffset() called after NO_MORE_DOCS";
assert positionCount > 0 : "endOffset() called before nextPosition()!";
return super.endOffset();
}
@Override
public BytesRef getPayload() throws IOException {
assert state != DocsEnumState.START : "getPayload() called before nextDoc()/advance()";
assert state != DocsEnumState.FINISHED : "getPayload() called after NO_MORE_DOCS";
assert positionCount > 0 : "getPayload() called before nextPosition()!";
return super.getPayload();
}
@Override
public boolean hasPayload() {
assert state != DocsEnumState.START : "hasPayload() called before nextDoc()/advance()";
assert state != DocsEnumState.FINISHED : "hasPayload() called after NO_MORE_DOCS";
assert positionCount > 0 : "hasPayload() called before nextPosition()!";
return super.hasPayload();
}
}
}

View File

@ -0,0 +1,90 @@
package org.apache.lucene.index;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import java.util.List;
/**
* A {@link DirectoryReader} that wraps all its subreaders with
* {@link AssertingAtomicReader}
*/
public class AssertingDirectoryReader extends DirectoryReader {
protected DirectoryReader in;
public AssertingDirectoryReader(DirectoryReader in) {
super(in.directory(), wrap(in.getSequentialSubReaders()));
this.in = in;
}
private static AtomicReader[] wrap(List<? extends AtomicReader> readers) {
AtomicReader[] wrapped = new AtomicReader[readers.size()];
for (int i = 0; i < readers.size(); i++) {
wrapped[i] = new AssertingAtomicReader(readers.get(i));
}
return wrapped;
}
@Override
protected DirectoryReader doOpenIfChanged() throws IOException {
DirectoryReader d = in.doOpenIfChanged();
return d == null ? null : new AssertingDirectoryReader(d);
}
@Override
protected DirectoryReader doOpenIfChanged(IndexCommit commit) throws IOException {
DirectoryReader d = in.doOpenIfChanged(commit);
return d == null ? null : new AssertingDirectoryReader(d);
}
@Override
protected DirectoryReader doOpenIfChanged(IndexWriter writer, boolean applyAllDeletes) throws IOException {
DirectoryReader d = in.doOpenIfChanged(writer, applyAllDeletes);
return d == null ? null : new AssertingDirectoryReader(d);
}
@Override
public long getVersion() {
return in.getVersion();
}
@Override
public boolean isCurrent() throws IOException {
return in.isCurrent();
}
@Override
public IndexCommit getIndexCommit() throws IOException {
return in.getIndexCommit();
}
@Override
protected void doClose() throws IOException {
in.doClose();
}
@Override
public Object getCoreCacheKey() {
return in.getCoreCacheKey();
}
@Override
public Object getCombinedCoreAndDeletesKey() {
return in.getCombinedCoreAndDeletesKey();
}
}

View File

@ -28,6 +28,7 @@ import java.util.Random;
import java.util.Set;
import org.apache.lucene.codecs.PostingsFormat;
import org.apache.lucene.codecs.asserting.AssertingPostingsFormat;
import org.apache.lucene.codecs.lucene40.Lucene40Codec;
import org.apache.lucene.codecs.lucene40.Lucene40PostingsFormat;
import org.apache.lucene.codecs.lucene40ords.Lucene40WithOrds;
@ -99,6 +100,7 @@ public class RandomCodec extends Lucene40Codec {
new NestedPulsingPostingsFormat(),
new Lucene40WithOrds(),
new SimpleTextPostingsFormat(),
new AssertingPostingsFormat(),
new MemoryPostingsFormat(true, random.nextFloat()),
new MemoryPostingsFormat(false, random.nextFloat()));

View File

@ -1010,7 +1010,7 @@ public abstract class LuceneTestCase extends Assert {
// TODO: remove this, and fix those tests to wrap before putting slow around:
final boolean wasOriginallyAtomic = r instanceof AtomicReader;
for (int i = 0, c = random.nextInt(6)+1; i < c; i++) {
switch(random.nextInt(4)) {
switch(random.nextInt(5)) {
case 0:
r = SlowCompositeReaderWrapper.wrap(r);
break;
@ -1041,6 +1041,16 @@ public abstract class LuceneTestCase extends Assert {
new FieldFilterAtomicReader(ar, fields, true)
);
break;
case 4:
// Häckidy-Hick-Hack: a standard Reader will cause FC insanity, so we use
// QueryUtils' reader with a fake cache key, so insanity checker cannot walk
// along our reader:
if (r instanceof AtomicReader) {
r = new FCInvisibleMultiReader(new AssertingAtomicReader((AtomicReader)r));
} else if (r instanceof DirectoryReader) {
r = new FCInvisibleMultiReader(new AssertingDirectoryReader((DirectoryReader)r));
}
break;
default:
fail("should not get here");
}

View File

@ -30,6 +30,7 @@ import java.util.TimeZone;
import org.apache.lucene.codecs.Codec;
import org.apache.lucene.codecs.PostingsFormat;
import org.apache.lucene.codecs.appending.AppendingCodec;
import org.apache.lucene.codecs.asserting.AssertingCodec;
import org.apache.lucene.codecs.lucene40.Lucene40Codec;
import org.apache.lucene.codecs.mockrandom.MockRandomPostingsFormat;
import org.apache.lucene.codecs.simpletext.SimpleTextCodec;
@ -189,6 +190,8 @@ final class TestRuleSetupAndRestoreClassEnv extends AbstractBeforeAfterRule {
codec = new SimpleTextCodec();
} else if ("Appending".equals(TEST_CODEC) || ("random".equals(TEST_CODEC) && randomVal == 8 && !shouldAvoidCodec("Appending"))) {
codec = new AppendingCodec();
} else if ("Asserting".equals(TEST_CODEC) || ("random".equals(TEST_CODEC) && randomVal == 7 && !shouldAvoidCodec("Asserting"))) {
codec = new AssertingCodec();
} else if (!"random".equals(TEST_CODEC)) {
codec = Codec.forName(TEST_CODEC);
} else if ("random".equals(TEST_POSTINGSFORMAT)) {

View File

@ -13,3 +13,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
org.apache.lucene.codecs.asserting.AssertingCodec

View File

@ -20,3 +20,5 @@ org.apache.lucene.codecs.mocksep.MockSepPostingsFormat
org.apache.lucene.codecs.nestedpulsing.NestedPulsingPostingsFormat
org.apache.lucene.codecs.ramonly.RAMOnlyPostingsFormat
org.apache.lucene.codecs.lucene40ords.Lucene40WithOrds
org.apache.lucene.codecs.asserting.AssertingPostingsFormat