summaryrefslogtreecommitdiff
path: root/core/src/main/java/org/apache/lucene/search/grouping/CollapsingDocValuesSource.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java/org/apache/lucene/search/grouping/CollapsingDocValuesSource.java')
-rw-r--r--core/src/main/java/org/apache/lucene/search/grouping/CollapsingDocValuesSource.java149
1 files changed, 100 insertions, 49 deletions
diff --git a/core/src/main/java/org/apache/lucene/search/grouping/CollapsingDocValuesSource.java b/core/src/main/java/org/apache/lucene/search/grouping/CollapsingDocValuesSource.java
index 5bc8afb347..e487733890 100644
--- a/core/src/main/java/org/apache/lucene/search/grouping/CollapsingDocValuesSource.java
+++ b/core/src/main/java/org/apache/lucene/search/grouping/CollapsingDocValuesSource.java
@@ -22,31 +22,32 @@ import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.DocValuesType;
import org.apache.lucene.index.FieldInfo;
import org.apache.lucene.index.LeafReader;
+import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.NumericDocValues;
import org.apache.lucene.index.SortedDocValues;
import org.apache.lucene.index.SortedNumericDocValues;
import org.apache.lucene.index.SortedSetDocValues;
-import org.apache.lucene.util.ArrayUtil;
-import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
+import org.elasticsearch.index.fielddata.AbstractNumericDocValues;
+import org.elasticsearch.index.fielddata.AbstractSortedDocValues;
import java.io.IOException;
+import java.util.Collection;
/**
* Utility class that ensures that a single collapse key is extracted per document.
*/
-abstract class CollapsingDocValuesSource<T> {
+abstract class CollapsingDocValuesSource<T> extends GroupSelector<T> {
protected final String field;
CollapsingDocValuesSource(String field) throws IOException {
this.field = field;
}
- abstract T get(int doc);
-
- abstract T copy(T value, T reuse);
-
- abstract void setNextReader(LeafReader reader) throws IOException;
+ @Override
+ public void setGroups(Collection<SearchGroup<T>> groups) {
+ throw new UnsupportedOperationException();
+ }
/**
* Implementation for {@link NumericDocValues} and {@link SortedNumericDocValues}.
@@ -54,35 +55,43 @@ abstract class CollapsingDocValuesSource<T> {
*/
static class Numeric extends CollapsingDocValuesSource<Long> {
private NumericDocValues values;
- private Bits docsWithField;
+ private long value;
+ private boolean hasValue;
Numeric(String field) throws IOException {
super(field);
}
@Override
- public Long get(int doc) {
- if (docsWithField.get(doc)) {
- return values.get(doc);
+ public State advanceTo(int doc) throws IOException {
+ if (values.advanceExact(doc)) {
+ hasValue = true;
+ value = values.longValue();
+ return State.ACCEPT;
} else {
- return null;
+ hasValue = false;
+ return State.SKIP;
}
}
@Override
- public Long copy(Long value, Long reuse) {
- return value;
+ public Long currentValue() {
+ return hasValue ? value : null;
}
@Override
- public void setNextReader(LeafReader reader) throws IOException {
+ public Long copyValue() {
+ return currentValue();
+ }
+
+ @Override
+ public void setNextReader(LeafReaderContext readerContext) throws IOException {
+ LeafReader reader = readerContext.reader();
DocValuesType type = getDocValuesType(reader, field);
if (type == null || type == DocValuesType.NONE) {
values = DocValues.emptyNumeric();
- docsWithField = new Bits.MatchNoBits(reader.maxDoc());
return ;
}
- docsWithField = DocValues.getDocsWithField(reader, field);
switch (type) {
case NUMERIC:
values = DocValues.getNumeric(reader, field);
@@ -92,17 +101,34 @@ abstract class CollapsingDocValuesSource<T> {
final SortedNumericDocValues sorted = DocValues.getSortedNumeric(reader, field);
values = DocValues.unwrapSingleton(sorted);
if (values == null) {
- values = new NumericDocValues() {
+ values = new AbstractNumericDocValues() {
+
+ private long value;
+
@Override
- public long get(int docID) {
- sorted.setDocument(docID);
- assert sorted.count() > 0;
- if (sorted.count() > 1) {
- throw new IllegalStateException("failed to collapse " + docID +
- ", the collapse field must be single valued");
+ public boolean advanceExact(int target) throws IOException {
+ if (sorted.advanceExact(target)) {
+ if (sorted.docValueCount() > 1) {
+ throw new IllegalStateException("failed to collapse " + target +
+ ", the collapse field must be single valued");
+ }
+ value = sorted.nextValue();
+ return true;
+ } else {
+ return false;
}
- return sorted.valueAt(0);
}
+
+ @Override
+ public int docID() {
+ return sorted.docID();
+ }
+
+ @Override
+ public long longValue() throws IOException {
+ return value;
+ }
+
};
}
break;
@@ -119,47 +145,56 @@ abstract class CollapsingDocValuesSource<T> {
* Fails with an {@link IllegalStateException} if a document contains multiple values for the specified field.
*/
static class Keyword extends CollapsingDocValuesSource<BytesRef> {
- private Bits docsWithField;
private SortedDocValues values;
+ private int ord;
Keyword(String field) throws IOException {
super(field);
}
@Override
- public BytesRef get(int doc) {
- if (docsWithField.get(doc)) {
- return values.get(doc);
+ public org.apache.lucene.search.grouping.GroupSelector.State advanceTo(int doc)
+ throws IOException {
+ if (values.advanceExact(doc)) {
+ ord = values.ordValue();
+ return State.ACCEPT;
} else {
+ ord = -1;
+ return State.SKIP;
+ }
+ }
+
+ @Override
+ public BytesRef currentValue() {
+ if (ord == -1) {
return null;
+ } else {
+ try {
+ return values.lookupOrd(ord);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
}
}
@Override
- public BytesRef copy(BytesRef value, BytesRef reuse) {
+ public BytesRef copyValue() {
+ BytesRef value = currentValue();
if (value == null) {
return null;
- }
- if (reuse != null) {
- reuse.bytes = ArrayUtil.grow(reuse.bytes, value.length);
- reuse.offset = 0;
- reuse.length = value.length;
- System.arraycopy(value.bytes, value.offset, reuse.bytes, 0, value.length);
- return reuse;
} else {
return BytesRef.deepCopyOf(value);
}
}
@Override
- public void setNextReader(LeafReader reader) throws IOException {
+ public void setNextReader(LeafReaderContext readerContext) throws IOException {
+ LeafReader reader = readerContext.reader();
DocValuesType type = getDocValuesType(reader, field);
if (type == null || type == DocValuesType.NONE) {
values = DocValues.emptySorted();
- docsWithField = new Bits.MatchNoBits(reader.maxDoc());
return ;
}
- docsWithField = DocValues.getDocsWithField(reader, field);
switch (type) {
case SORTED:
values = DocValues.getSorted(reader, field);
@@ -169,20 +204,36 @@ abstract class CollapsingDocValuesSource<T> {
final SortedSetDocValues sorted = DocValues.getSortedSet(reader, field);
values = DocValues.unwrapSingleton(sorted);
if (values == null) {
- values = new SortedDocValues() {
+ values = new AbstractSortedDocValues() {
+
+ private int ord;
+
@Override
- public int getOrd(int docID) {
- sorted.setDocument(docID);
- int ord = (int) sorted.nextOrd();
- if (sorted.nextOrd() != SortedSetDocValues.NO_MORE_ORDS) {
- throw new IllegalStateException("failed to collapse " + docID +
- ", the collapse field must be single valued");
+ public boolean advanceExact(int target) throws IOException {
+ if (sorted.advanceExact(target)) {
+ ord = (int) sorted.nextOrd();
+ if (sorted.nextOrd() != SortedSetDocValues.NO_MORE_ORDS) {
+ throw new IllegalStateException("failed to collapse " + target +
+ ", the collapse field must be single valued");
+ }
+ return true;
+ } else {
+ return false;
}
+ }
+
+ @Override
+ public int docID() {
+ return sorted.docID();
+ }
+
+ @Override
+ public int ordValue() {
return ord;
}
@Override
- public BytesRef lookupOrd(int ord) {
+ public BytesRef lookupOrd(int ord) throws IOException {
return sorted.lookupOrd(ord);
}