aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo/search/rendering
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@oath.com>2018-05-11 19:10:58 +0200
committerGitHub <noreply@github.com>2018-05-11 19:10:58 +0200
commit40e9964ea6f7e9940aebd45591822cb7982a914d (patch)
treeed9b0986dbe39e57c55f003679a07fbf9acc42a9 /container-search/src/main/java/com/yahoo/search/rendering
parentcf80ff1b7ce08cd3fdfd8c789de45da02ffba5c9 (diff)
Revert "Revert "Bratseth/allocation free hit field traversal""
Diffstat (limited to 'container-search/src/main/java/com/yahoo/search/rendering')
-rw-r--r--container-search/src/main/java/com/yahoo/search/rendering/DefaultRenderer.java23
-rw-r--r--container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java66
-rw-r--r--container-search/src/main/java/com/yahoo/search/rendering/SyncDefaultRenderer.java31
3 files changed, 49 insertions, 71 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/rendering/DefaultRenderer.java b/container-search/src/main/java/com/yahoo/search/rendering/DefaultRenderer.java
index bae1185d6a9..2d69a262f15 100644
--- a/container-search/src/main/java/com/yahoo/search/rendering/DefaultRenderer.java
+++ b/container-search/src/main/java/com/yahoo/search/rendering/DefaultRenderer.java
@@ -185,28 +185,19 @@ public final class DefaultRenderer extends AsynchronousSectionedRenderer<Result>
private void renderHitFields(XMLWriter writer, Hit hit) {
renderSyntheticRelevanceField(writer, hit);
- for (Iterator<Map.Entry<String, Object>> it = hit.fieldIterator(); it.hasNext(); ) {
- renderField(writer, hit, it);
- }
- }
-
- private void renderField(XMLWriter writer, Hit hit, Iterator<Map.Entry<String, Object>> it) {
- renderGenericField(writer, hit, it.next());
+ hit.forEachField((name, value) -> renderField(writer, name, value));
}
- private void renderGenericField(XMLWriter writer, Hit hit, Map.Entry<String, Object> entry) {
- String fieldName = entry.getKey();
-
- // skip depending on hit type
- if (fieldName.startsWith("$")) return; // Don't render fields that start with $ // TODO: Move to should render
+ private void renderField(XMLWriter writer, String name, Object value) {
+ if (name.startsWith("$")) return;
- writeOpenFieldElement(writer, fieldName);
- renderFieldContent(writer, hit, fieldName);
+ writeOpenFieldElement(writer, name);
+ renderFieldContent(writer, value);
writeCloseFieldElement(writer);
}
- private void renderFieldContent(XMLWriter writer, Hit hit, String fieldName) {
- writer.escapedContent(asXML(hit.getField(fieldName)), false);
+ private void renderFieldContent(XMLWriter writer, Object value) {
+ writer.escapedContent(asXML(value), false);
}
private String asXML(Object value) {
diff --git a/container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java b/container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java
index 34b02b1bee8..6c7018317c3 100644
--- a/container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java
+++ b/container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java
@@ -14,7 +14,7 @@ import com.yahoo.document.datatypes.FieldValue;
import com.yahoo.document.datatypes.StringFieldValue;
import com.yahoo.document.datatypes.TensorFieldValue;
import com.yahoo.document.json.JsonWriter;
-import com.yahoo.prelude.fastsearch.FastHit;
+import com.yahoo.lang.MutableBoolean;
import com.yahoo.processing.Response;
import com.yahoo.processing.execution.Execution.Trace;
import com.yahoo.processing.rendering.AsynchronousSectionedRenderer;
@@ -49,6 +49,7 @@ import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.io.UncheckedIOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
@@ -472,14 +473,14 @@ public class JsonRenderer extends AsynchronousSectionedRenderer<Result> {
return ! (hit instanceof DefaultErrorHit);
}
- private boolean fieldsStart(boolean hasFieldsField) throws IOException {
- if (hasFieldsField) return true;
+ private void fieldsStart(MutableBoolean hasFieldsField) throws IOException {
+ if (hasFieldsField.get()) return;
generator.writeObjectFieldStart(FIELDS);
- return true;
+ hasFieldsField.set(true);
}
- private void fieldsEnd(boolean hasFieldsField) throws IOException {
- if (!hasFieldsField) return;
+ private void fieldsEnd(MutableBoolean hasFieldsField) throws IOException {
+ if ( ! hasFieldsField.get()) return;
generator.writeEndObject();
}
@@ -508,39 +509,37 @@ public class JsonRenderer extends AsynchronousSectionedRenderer<Result> {
}
private void renderAllFields(Hit hit) throws IOException {
- boolean hasFieldsField = false;
-
- hasFieldsField |= renderTotalHitCount(hit, hasFieldsField);
- hasFieldsField |= renderStandardFields(hit, hasFieldsField);
+ MutableBoolean hasFieldsField = new MutableBoolean(false);
+ renderTotalHitCount(hit, hasFieldsField);
+ renderStandardFields(hit, hasFieldsField);
fieldsEnd(hasFieldsField);
}
- private boolean renderStandardFields(Hit hit, boolean initialHasFieldsField) throws IOException {
- boolean hasFieldsField = initialHasFieldsField;
- for (String fieldName : hit.fieldKeys()) {
- if (!shouldRender(fieldName, hit)) continue;
-
- // We can't look at the size of fieldKeys() and know whether we need
- // the fields object, as all fields may be hidden.
- hasFieldsField |= fieldsStart(hasFieldsField);
- renderField(fieldName, hit);
- }
- return hasFieldsField;
+ private void renderStandardFields(Hit hit, MutableBoolean hasFieldsField) {
+ hit.forEachField((name, value) -> {
+ try {
+ if (shouldRender(name, value)) {
+ fieldsStart(hasFieldsField);
+ renderField(name, value);
+ }
+ }
+ catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ });
}
- private boolean shouldRender(String fieldName, Hit hit) {
+ private boolean shouldRender(String name, Object value) {
if (debugRendering) return true;
- if (fieldName.startsWith(VESPA_HIDDEN_FIELD_PREFIX)) return false;
+ if (name.startsWith(VESPA_HIDDEN_FIELD_PREFIX)) return false;
- Object field = hit.getField(fieldName);
-
- if (field instanceof CharSequence && ((CharSequence) field).length() == 0) return false;
+ if (value instanceof CharSequence && ((CharSequence) value).length() == 0) return false;
// StringFieldValue cannot hold a null, so checking length directly is OK:
- if (field instanceof StringFieldValue && ((StringFieldValue) field).getString().isEmpty()) return false;
+ if (value instanceof StringFieldValue && ((StringFieldValue) value).getString().isEmpty()) return false;
- if (field instanceof NanNumber) return false;
+ if (value instanceof NanNumber) return false;
return true;
}
@@ -607,17 +606,16 @@ public class JsonRenderer extends AsynchronousSectionedRenderer<Result> {
return (id instanceof RawBucketId ? Arrays.toString(((RawBucketId) id).getTo()) : id.getTo()).toString();
}
- private boolean renderTotalHitCount(Hit hit, boolean hasFieldsField) throws IOException {
- if ( ! (getRecursionLevel() == 1 && hit instanceof HitGroup)) return false;
+ private void renderTotalHitCount(Hit hit, MutableBoolean hasFieldsField) throws IOException {
+ if ( ! (getRecursionLevel() == 1 && hit instanceof HitGroup)) return;
fieldsStart(hasFieldsField);
generator.writeNumberField(TOTAL_COUNT, getResult().getTotalHitCount());
- return true;
}
- private void renderField(String fieldName, Hit hit) throws IOException {
- generator.writeFieldName(fieldName);
- renderFieldContents(hit.getField(fieldName));
+ private void renderField(String name, Object value) throws IOException {
+ generator.writeFieldName(name);
+ renderFieldContents(value);
}
private void renderFieldContents(Object field) throws IOException {
diff --git a/container-search/src/main/java/com/yahoo/search/rendering/SyncDefaultRenderer.java b/container-search/src/main/java/com/yahoo/search/rendering/SyncDefaultRenderer.java
index dc72061e224..08599540cb1 100644
--- a/container-search/src/main/java/com/yahoo/search/rendering/SyncDefaultRenderer.java
+++ b/container-search/src/main/java/com/yahoo/search/rendering/SyncDefaultRenderer.java
@@ -271,25 +271,19 @@ public final class SyncDefaultRenderer extends Renderer {
private void renderHitFields(XMLWriter writer, Hit hit) {
renderSyntheticRelevanceField(writer, hit);
- for (Iterator<Map.Entry<String, Object>> it = hit.fieldIterator(); it.hasNext(); ) {
- renderField(writer, hit, it);
- }
+ hit.forEachField((name, value) -> renderField(writer, name, value));
}
- private void renderField(XMLWriter writer, Hit hit, Iterator<Map.Entry<String, Object>> it) {
- Map.Entry<String, Object> entry = it.next();
- String fieldName = entry.getKey();
-
- if ( ! shouldRenderField(hit, fieldName)) return;
- if (fieldName.startsWith("$")) return; // Don't render fields that start with $ // TODO: Move to should render
+ private void renderField(XMLWriter writer, String name, Object value) {
+ if (name.startsWith("$")) return;
- writeOpenFieldElement(writer, fieldName);
- renderFieldContent(writer, hit, fieldName);
+ writeOpenFieldElement(writer, name);
+ renderFieldContent(writer, value);
writeCloseFieldElement(writer);
}
- private void renderFieldContent(XMLWriter writer, Hit hit, String fieldName) {
- writer.escapedContent(asXML(hit.getField(fieldName)), false);
+ private void renderFieldContent(XMLWriter writer, Object value) {
+ writer.escapedContent(asXML(value), false);
}
private String asXML(Object value) {
@@ -304,10 +298,10 @@ public final class SyncDefaultRenderer extends Renderer {
}
private void renderSyntheticRelevanceField(XMLWriter writer, Hit hit) {
- final String relevancyFieldName = "relevancy";
- final Relevance relevance = hit.getRelevance();
+ String relevancyFieldName = "relevancy";
+ Relevance relevance = hit.getRelevance();
- if (shouldRenderField(hit, relevancyFieldName) && relevance != null) {
+ if (relevance != null) {
renderSimpleField(writer, relevancyFieldName, relevance);
}
}
@@ -332,11 +326,6 @@ public final class SyncDefaultRenderer extends Renderer {
writer.closeStartTag();
}
- private boolean shouldRenderField(Hit hit, String relevancyFieldName) {
- // skip depending on hit type
- return true;
- }
-
private void renderHitAttributes(XMLWriter writer, Hit hit) {
writer.attribute(TYPE, hit.types().stream().collect(Collectors.joining(" ")));
if (hit.getRelevance() != null) {