add specific makeSafe method to make an unsafe (shared) bytes based value to a "safe" one

This commit is contained in:
Shay Banon 2013-01-20 15:01:31 +01:00
parent 1765b0b813
commit d88e3f73ac
4 changed files with 48 additions and 8 deletions

View File

@ -28,15 +28,20 @@ import org.elasticsearch.index.fielddata.util.StringArrayRef;
*/ */
public interface BytesValues { public interface BytesValues {
/**
* Is one of the documents in this field data values is multi valued?
*/
boolean isMultiValued();
/** /**
* Is there a value for this doc? * Is there a value for this doc?
*/ */
boolean hasValue(int docId); boolean hasValue(int docId);
/** /**
* Is one of the documents in this field data values is multi valued? * Converts the provided bytes to "safe" ones from a "non" safe call made (if needed).
*/ */
boolean isMultiValued(); BytesRef makeSafe(BytesRef bytes);
/** /**
* Returns a bytes value for a docId. Note, the content of it might be shared across invocation. * Returns a bytes value for a docId. Note, the content of it might be shared across invocation.
@ -147,14 +152,20 @@ public interface BytesValues {
this.values = values; this.values = values;
} }
@Override
public boolean isMultiValued() {
return values.isMultiValued();
}
@Override @Override
public boolean hasValue(int docId) { public boolean hasValue(int docId) {
return values.hasValue(docId); return values.hasValue(docId);
} }
@Override @Override
public boolean isMultiValued() { public BytesRef makeSafe(BytesRef bytes) {
return values.isMultiValued(); // we need to make a copy, since we use scratch to provide it
return BytesRef.deepCopyOf(bytes);
} }
@Override @Override

View File

@ -37,6 +37,11 @@ public interface HashedBytesValues {
*/ */
boolean hasValue(int docId); boolean hasValue(int docId);
/**
* Converts the provided bytes to "safe" ones from a "non" safe call made (if needed).
*/
HashedBytesRef makeSafe(HashedBytesRef bytes);
/** /**
* Returns a bytes value for a docId. Note, the content of it might be shared across invocation. * Returns a bytes value for a docId. Note, the content of it might be shared across invocation.
*/ */
@ -146,6 +151,11 @@ public interface HashedBytesValues {
return values.hasValue(docId); return values.hasValue(docId);
} }
@Override
public HashedBytesRef makeSafe(HashedBytesRef bytes) {
return new HashedBytesRef(values.makeSafe(bytes.bytes), bytes.hash);
}
@Override @Override
public HashedBytesRef getValue(int docId) { public HashedBytesRef getValue(int docId) {
BytesRef value = values.getValue(docId); BytesRef value = values.getValue(docId);
@ -289,6 +299,12 @@ public interface HashedBytesValues {
return values.hasValue(docId); return values.hasValue(docId);
} }
@Override
public HashedBytesRef makeSafe(HashedBytesRef bytes) {
// we use scratch to provide it, so just need to copy it over to a new instance
return new HashedBytesRef(bytes.bytes, bytes.hash);
}
@Override @Override
public HashedBytesRef getValue(int docId) { public HashedBytesRef getValue(int docId) {
String value = values.getValue(docId); String value = values.getValue(docId);

View File

@ -146,6 +146,12 @@ public class ConcreteBytesRefAtomicFieldData implements AtomicOrdinalFieldData<S
return ordinals.getOrd(docId) != 0; return ordinals.getOrd(docId) != 0;
} }
@Override
public BytesRef makeSafe(BytesRef bytes) {
// no need to do anything, its already concrete bytes...
return bytes;
}
@Override @Override
public BytesRef getValue(int docId) { public BytesRef getValue(int docId) {
return values[ordinals.getOrd(docId)]; return values[ordinals.getOrd(docId)];
@ -337,6 +343,13 @@ public class ConcreteBytesRefAtomicFieldData implements AtomicOrdinalFieldData<S
return ordinals.getOrd(docId) != 0; return ordinals.getOrd(docId) != 0;
} }
@Override
public HashedBytesRef makeSafe(HashedBytesRef bytes) {
// we just need to create a copy of the bytes ref, no need
// to create a copy of the actual BytesRef, as its concrete
return new HashedBytesRef(bytes.bytes, bytes.hash);
}
@Override @Override
public HashedBytesRef getValue(int docId) { public HashedBytesRef getValue(int docId) {
int ord = ordinals.getOrd(docId); int ord = ordinals.getOrd(docId);

View File

@ -83,6 +83,7 @@ public class TermsStatsStringFacetCollector extends AbstractFacetCollector {
@Override @Override
protected void doSetNextReader(AtomicReaderContext context) throws IOException { protected void doSetNextReader(AtomicReaderContext context) throws IOException {
keyValues = keyIndexFieldData.load(context).getHashedBytesValues(); keyValues = keyIndexFieldData.load(context).getHashedBytesValues();
aggregator.keyValues = keyValues;
if (script != null) { if (script != null) {
script.setNextReader(context); script.setNextReader(context);
} else { } else {
@ -127,6 +128,7 @@ public class TermsStatsStringFacetCollector extends AbstractFacetCollector {
int missing = 0; int missing = 0;
HashedBytesValues keyValues;
DoubleValues valueValues; DoubleValues valueValues;
ValueAggregator valueAggregator = new ValueAggregator(); ValueAggregator valueAggregator = new ValueAggregator();
@ -135,8 +137,7 @@ public class TermsStatsStringFacetCollector extends AbstractFacetCollector {
public void onValue(int docId, HashedBytesRef value) { public void onValue(int docId, HashedBytesRef value) {
InternalTermsStatsStringFacet.StringEntry stringEntry = entries.get(value); InternalTermsStatsStringFacet.StringEntry stringEntry = entries.get(value);
if (stringEntry == null) { if (stringEntry == null) {
// we use "unsafe" hashedBytes, and only copy over if we "miss" on the map, and need to put it there value = keyValues.makeSafe(value);
value = value.deepCopy();
stringEntry = new InternalTermsStatsStringFacet.StringEntry(value, 0, 0, 0, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY); stringEntry = new InternalTermsStatsStringFacet.StringEntry(value, 0, 0, 0, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY);
entries.put(value, stringEntry); entries.put(value, stringEntry);
} }
@ -183,8 +184,7 @@ public class TermsStatsStringFacetCollector extends AbstractFacetCollector {
public void onValue(int docId, HashedBytesRef value) { public void onValue(int docId, HashedBytesRef value) {
InternalTermsStatsStringFacet.StringEntry stringEntry = entries.get(value); InternalTermsStatsStringFacet.StringEntry stringEntry = entries.get(value);
if (stringEntry == null) { if (stringEntry == null) {
// we use "unsafe" hashedBytes, and only copy over if we "miss" on the map, and need to put it there value = keyValues.makeSafe(value);
value = value.deepCopy();
stringEntry = new InternalTermsStatsStringFacet.StringEntry(value, 1, 0, 0, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY); stringEntry = new InternalTermsStatsStringFacet.StringEntry(value, 1, 0, 0, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY);
entries.put(value, stringEntry); entries.put(value, stringEntry);
} else { } else {