diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/idversion/IDVersionPostingsReader.java b/lucene/codecs/src/java/org/apache/lucene/codecs/idversion/IDVersionPostingsReader.java index df04bd8a2cb..5bc8a640c29 100644 --- a/lucene/codecs/src/java/org/apache/lucene/codecs/idversion/IDVersionPostingsReader.java +++ b/lucene/codecs/src/java/org/apache/lucene/codecs/idversion/IDVersionPostingsReader.java @@ -61,14 +61,31 @@ public final class IDVersionPostingsReader extends PostingsReaderBase { @Override public DocsEnum docs(FieldInfo fieldInfo, BlockTermState termState, Bits liveDocs, DocsEnum reuse, int flags) throws IOException { - // nocommit todo -- need a SingleDocDocsEnum - return null; + SingleDocsEnum docsEnum; + + if (reuse instanceof SingleDocsEnum) { + docsEnum = (SingleDocsEnum) reuse; + } else { + docsEnum = new SingleDocsEnum(); + } + docsEnum.reset(((IDVersionTermState) termState).docID, liveDocs); + + return docsEnum; } @Override - public DocsAndPositionsEnum docsAndPositions(FieldInfo fieldInfo, BlockTermState termState, Bits liveDocs, + public DocsAndPositionsEnum docsAndPositions(FieldInfo fieldInfo, BlockTermState _termState, Bits liveDocs, DocsAndPositionsEnum reuse, int flags) { - return null; + SingleDocsAndPositionsEnum posEnum; + + if (reuse instanceof SingleDocsAndPositionsEnum) { + posEnum = (SingleDocsAndPositionsEnum) reuse; + } else { + posEnum = new SingleDocsAndPositionsEnum(); + } + IDVersionTermState termState = (IDVersionTermState) _termState; + posEnum.reset(termState.docID, termState.idVersion, liveDocs); + return posEnum; } @Override diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/idversion/SingleDocsAndPositionsEnum.java b/lucene/codecs/src/java/org/apache/lucene/codecs/idversion/SingleDocsAndPositionsEnum.java new file mode 100644 index 00000000000..bb19e9443a6 --- /dev/null +++ b/lucene/codecs/src/java/org/apache/lucene/codecs/idversion/SingleDocsAndPositionsEnum.java @@ -0,0 +1,100 @@ +package org.apache.lucene.codecs.idversion; + +/* + * 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.index.DocsAndPositionsEnum; +import org.apache.lucene.util.Bits; +import org.apache.lucene.util.BytesRef; + +class SingleDocsAndPositionsEnum extends DocsAndPositionsEnum { + private int doc; + private int pos; + private int singleDocID; + private Bits liveDocs; + private long version; + private final BytesRef payload = new BytesRef(); + + /** For reuse */ + public void reset(int singleDocID, long version, Bits liveDocs) { + doc = -1; + this.liveDocs = liveDocs; + this.singleDocID = singleDocID; + this.version = version; + pos = -1; + } + + @Override + public int nextDoc() { + if (doc == -1 && (liveDocs == null || liveDocs.get(singleDocID))) { + doc = singleDocID; + } else { + doc = NO_MORE_DOCS; + } + pos = 0; + + return doc; + } + + @Override + public int docID() { + return doc; + } + + @Override + public int advance(int target) { + if (doc == -1 && target <= singleDocID && (liveDocs == null || liveDocs.get(singleDocID))) { + doc = singleDocID; + } else { + doc = NO_MORE_DOCS; + } + return doc; + } + + @Override + public long cost() { + return 1; + } + + @Override + public int freq() { + return 1; + } + + @Override + public int nextPosition() { + assert pos == -1; + pos = 0; + // nocommit re-encode version back into payload here: + return pos; + } + + @Override + public BytesRef getPayload() { + return payload; + } + + @Override + public int startOffset() { + return -1; + } + + @Override + public int endOffset() { + return -1; + } +} diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/idversion/SingleDocsEnum.java b/lucene/codecs/src/java/org/apache/lucene/codecs/idversion/SingleDocsEnum.java new file mode 100644 index 00000000000..b29619c7af6 --- /dev/null +++ b/lucene/codecs/src/java/org/apache/lucene/codecs/idversion/SingleDocsEnum.java @@ -0,0 +1,71 @@ +package org.apache.lucene.codecs.idversion; + +/* + * 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.index.DocsEnum; +import org.apache.lucene.util.Bits; + +class SingleDocsEnum extends DocsEnum { + + private int doc; + private int singleDocID; + private Bits liveDocs; + + /** For reuse */ + public void reset(int singleDocID, Bits liveDocs) { + doc = -1; + this.liveDocs = liveDocs; + this.singleDocID = singleDocID; + } + + @Override + public int nextDoc() { + if (doc == -1 && (liveDocs == null || liveDocs.get(singleDocID))) { + doc = singleDocID; + } else { + doc = NO_MORE_DOCS; + } + + return doc; + } + + @Override + public int docID() { + return doc; + } + + @Override + public int advance(int target) { + if (doc == -1 && target <= singleDocID && (liveDocs == null || liveDocs.get(singleDocID))) { + doc = singleDocID; + } else { + doc = NO_MORE_DOCS; + } + return doc; + } + + @Override + public long cost() { + return 1; + } + + @Override + public int freq() { + return 1; + } +} diff --git a/lucene/codecs/src/resources/META-INF/services/org.apache.lucene.codecs.PostingsFormat b/lucene/codecs/src/resources/META-INF/services/org.apache.lucene.codecs.PostingsFormat index 40a0c3550e8..acadf5b48aa 100644 --- a/lucene/codecs/src/resources/META-INF/services/org.apache.lucene.codecs.PostingsFormat +++ b/lucene/codecs/src/resources/META-INF/services/org.apache.lucene.codecs.PostingsFormat @@ -22,3 +22,4 @@ org.apache.lucene.codecs.memory.FSTPulsing41PostingsFormat org.apache.lucene.codecs.memory.FSTOrdPulsing41PostingsFormat org.apache.lucene.codecs.memory.FSTPostingsFormat org.apache.lucene.codecs.memory.FSTOrdPostingsFormat +org.apache.lucene.codecs.idversion.IDVersionPostingsFormat diff --git a/lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsReader.java b/lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsReader.java index 54e37e5a05b..18c81de4926 100644 --- a/lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsReader.java +++ b/lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsReader.java @@ -1318,6 +1318,8 @@ public class BlockTreeTermsReader extends FieldsProducer { private Frame currentFrame; private boolean termExists; + // nocommit make this public "for casting" and add a getVersion method? + private int targetBeforeCurrentLength; private final ByteArrayDataInput scratchReader = new ByteArrayDataInput(); @@ -1560,6 +1562,8 @@ public class BlockTreeTermsReader extends FieldsProducer { return true; } + // nocommit we need a seekExact(BytesRef target, long minVersion) API? + @Override public boolean seekExact(final BytesRef target) throws IOException {