diff --git a/src/main/java/org/elasticsearch/index/fielddata/FilterBytesValues.java b/src/main/java/org/elasticsearch/index/fielddata/FilterBytesValues.java deleted file mode 100644 index a652106cf54be..0000000000000 --- a/src/main/java/org/elasticsearch/index/fielddata/FilterBytesValues.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. - */ -package org.elasticsearch.index.fielddata; - -import org.apache.lucene.util.BytesRef; - -/** - * FilterBytesValues contains another {@link BytesValues}, which it - * uses as its basic source of data, possibly transforming the data along the - * way or providing additional functionality. - */ -public abstract class FilterBytesValues extends BytesValues { - - protected final BytesValues delegate; - - protected FilterBytesValues(BytesValues delegate) { - super(delegate.isMultiValued()); - this.delegate = delegate; - } - - @Override - public BytesRef copyShared() { - return delegate.copyShared(); - } - - @Override - public int setDocument(int docId) { - return delegate.setDocument(docId); - } - - @Override - public BytesRef nextValue() { - return delegate.nextValue(); - } - - @Override - public int currentValueHash() { - return delegate.currentValueHash(); - } - - @Override - public AtomicFieldData.Order getOrder() { - return delegate.getOrder(); - } -} \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/search/aggregations/support/FieldDataSource.java b/src/main/java/org/elasticsearch/search/aggregations/support/FieldDataSource.java index 223e1502284ef..5d1152aefae54 100644 --- a/src/main/java/org/elasticsearch/search/aggregations/support/FieldDataSource.java +++ b/src/main/java/org/elasticsearch/search/aggregations/support/FieldDataSource.java @@ -287,23 +287,23 @@ public org.elasticsearch.index.fielddata.BytesValues bytesValues() { return bytesValues; } - static class SortedUniqueBytesValues extends FilterBytesValues { + static class SortedUniqueBytesValues extends BytesValues { - final BytesRef spare; + final BytesValues delegate; int[] sortedIds; final BytesRefHash bytes; int numUniqueValues; int pos = Integer.MAX_VALUE; public SortedUniqueBytesValues(BytesValues delegate) { - super(delegate); + super(delegate.isMultiValued()); + this.delegate = delegate; bytes = new BytesRefHash(); - spare = new BytesRef(); } @Override public int setDocument(int docId) { - final int numValues = super.setDocument(docId); + final int numValues = delegate.setDocument(docId); if (numValues == 0) { sortedIds = null; return 0; @@ -311,7 +311,10 @@ public int setDocument(int docId) { bytes.clear(); bytes.reinit(); for (int i = 0; i < numValues; ++i) { - bytes.add(super.nextValue(), super.currentValueHash()); + final BytesRef next = delegate.nextValue(); + final int hash = delegate.currentValueHash(); + assert hash == next.hashCode(); + bytes.add(next, hash); } numUniqueValues = bytes.size(); sortedIds = bytes.sort(BytesRef.getUTF8SortedAsUnicodeComparator()); @@ -321,13 +324,8 @@ public int setDocument(int docId) { @Override public BytesRef nextValue() { - bytes.get(sortedIds[pos++], spare); - return spare; - } - - @Override - public int currentValueHash() { - return spare.hashCode(); + bytes.get(sortedIds[pos++], scratch); + return scratch; } @Override @@ -738,13 +736,11 @@ static class BytesValues extends org.elasticsearch.index.fielddata.BytesValues { private final FieldDataSource source; private final SearchScript script; - private final BytesRef scratch; public BytesValues(FieldDataSource source, SearchScript script) { super(true); this.source = source; this.script = script; - scratch = new BytesRef(); } @Override diff --git a/src/main/java/org/elasticsearch/search/aggregations/support/bytes/ScriptBytesValues.java b/src/main/java/org/elasticsearch/search/aggregations/support/bytes/ScriptBytesValues.java index cd612b6102222..b7d46a74a326b 100644 --- a/src/main/java/org/elasticsearch/search/aggregations/support/bytes/ScriptBytesValues.java +++ b/src/main/java/org/elasticsearch/search/aggregations/support/bytes/ScriptBytesValues.java @@ -37,7 +37,6 @@ public class ScriptBytesValues extends BytesValues implements ScriptValues { private Iterator iter; private Object value; - private BytesRef scratch = new BytesRef(); public ScriptBytesValues(SearchScript script) { super(true); // assume multi-valued diff --git a/src/test/java/org/elasticsearch/search/aggregations/support/FieldDataSourceTests.java b/src/test/java/org/elasticsearch/search/aggregations/support/FieldDataSourceTests.java new file mode 100644 index 0000000000000..b9c1954b164dc --- /dev/null +++ b/src/test/java/org/elasticsearch/search/aggregations/support/FieldDataSourceTests.java @@ -0,0 +1,141 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch 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. + */ + +package org.elasticsearch.search.aggregations.support; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.search.Scorer; +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.index.fielddata.BytesValues; +import org.elasticsearch.script.SearchScript; +import org.elasticsearch.test.ElasticsearchTestCase; +import org.junit.Test; + +import java.util.Map; + +public class FieldDataSourceTests extends ElasticsearchTestCase { + + private static BytesValues randomBytesValues() { + final boolean multiValued = randomBoolean(); + return new BytesValues(multiValued) { + @Override + public int setDocument(int docId) { + return randomInt(multiValued ? 10 : 1); + } + @Override + public BytesRef nextValue() { + scratch.copyChars(randomAsciiOfLength(10)); + return scratch; + } + + }; + } + + private static SearchScript randomScript() { + return new SearchScript() { + + @Override + public void setNextVar(String name, Object value) { + } + + @Override + public Object run() { + return randomAsciiOfLength(5); + } + + @Override + public Object unwrap(Object value) { + return value; + } + + @Override + public void setNextReader(AtomicReaderContext reader) { + } + + @Override + public void setScorer(Scorer scorer) { + } + + @Override + public void setNextDocId(int doc) { + } + + @Override + public void setNextSource(Map source) { + } + + @Override + public void setNextScore(float score) { + } + + @Override + public float runAsFloat() { + throw new UnsupportedOperationException(); + } + + @Override + public long runAsLong() { + throw new UnsupportedOperationException(); + } + + @Override + public double runAsDouble() { + throw new UnsupportedOperationException(); + } + + }; + } + + private static void assertConsistent(BytesValues values) { + for (int i = 0; i < 10; ++i) { + final int valueCount = values.setDocument(i); + for (int j = 0; j < valueCount; ++j) { + final BytesRef term = values.nextValue(); + assertEquals(term.hashCode(), values.currentValueHash()); + assertTrue(term.bytesEquals(values.copyShared())); + } + } + } + + @Test + public void bytesValuesWithScript() { + final BytesValues values = randomBytesValues(); + FieldDataSource source = new FieldDataSource.Bytes() { + + @Override + public BytesValues bytesValues() { + return values; + } + + @Override + public MetaData metaData() { + throw new UnsupportedOperationException(); + } + + }; + SearchScript script = randomScript(); + assertConsistent(new FieldDataSource.WithScript.BytesValues(source, script)); + } + + @Test + public void sortedUniqueBytesValues() { + assertConsistent(new FieldDataSource.Bytes.SortedAndUnique.SortedUniqueBytesValues(randomBytesValues())); + } + +}