From 5c70134cc3cfdf214f55a874dea3e6cecf3a03af Mon Sep 17 00:00:00 2001 From: Armin Date: Sat, 14 Jul 2018 14:10:10 +0200 Subject: [PATCH] INGEST: Clean up Java8 Stream Usage * GrokProcessor: Rationalize the loop over the map to save allocations and indirection * KeyValueProcessor: Remove unnecessary Stream usage when looping over array and pre-build execution instead of redundantly evaluating null checks and string concatenation --- .../ingest/common/GrokProcessor.java | 3 +- .../ingest/common/KeyValueProcessor.java | 54 +++++++++++++------ .../elasticsearch/ingest/IngestDocument.java | 3 +- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/GrokProcessor.java b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/GrokProcessor.java index 7bb3ebfba6e36..88cba512b86cb 100644 --- a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/GrokProcessor.java +++ b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/GrokProcessor.java @@ -68,8 +68,7 @@ public void execute(IngestDocument ingestDocument) throws Exception { throw new IllegalArgumentException("Provided Grok expressions do not match field value: [" + fieldValue + "]"); } - matches.entrySet().stream() - .forEach((e) -> ingestDocument.setFieldValue(e.getKey(), e.getValue())); + matches.forEach(ingestDocument::setFieldValue); if (traceMatch) { if (matchPatterns.size() > 1) { diff --git a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/KeyValueProcessor.java b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/KeyValueProcessor.java index 6ed065926d60f..6a3c129ab6901 100644 --- a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/KeyValueProcessor.java +++ b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/KeyValueProcessor.java @@ -25,11 +25,12 @@ import org.elasticsearch.ingest.IngestDocument; import org.elasticsearch.ingest.Processor; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.Predicate; /** * The KeyValueProcessor parses and extracts messages of the `key=value` variety into fields with values of the keys. @@ -45,6 +46,7 @@ public final class KeyValueProcessor extends AbstractProcessor { private final Set excludeKeys; private final String targetField; private final boolean ignoreMissing; + private final BiConsumer execution; KeyValueProcessor(String tag, String field, String fieldSplit, String valueSplit, Set includeKeys, Set excludeKeys, String targetField, boolean ignoreMissing) { @@ -56,6 +58,39 @@ public final class KeyValueProcessor extends AbstractProcessor { this.includeKeys = includeKeys; this.excludeKeys = excludeKeys; this.ignoreMissing = ignoreMissing; + this.execution = buildExecution(fieldSplit, valueSplit, field, includeKeys, excludeKeys, targetField); + } + + private static BiConsumer buildExecution(String fieldSplit, String valueSplit, String field, + Set includeKeys, Set excludeKeys, + String targetField) { + final Predicate keyFilter; + if (includeKeys == null) { + if (excludeKeys == null) { + keyFilter = key -> true; + } else { + keyFilter = key -> excludeKeys.contains(key) == false; + } + } else { + if (excludeKeys == null) { + keyFilter = includeKeys::contains; + } else { + keyFilter = key -> includeKeys.contains(key) && excludeKeys.contains(key) == false; + } + } + String fieldPathPrefix = targetField == null ? "" : targetField + "."; + return (document, value) -> { + for (String part : value.split(fieldSplit)) { + String[] kv = part.split(valueSplit, 2); + if (kv.length != 2) { + throw new IllegalArgumentException("field [" + field + "] does not contain value_split [" + valueSplit + "]"); + } + String key = kv[0]; + if (keyFilter.test(key)) { + append(document, fieldPathPrefix + key, kv[1]); + } + } + }; } String getField() { @@ -86,7 +121,7 @@ boolean isIgnoreMissing() { return ignoreMissing; } - public void append(IngestDocument document, String targetField, String value) { + private static void append(IngestDocument document, String targetField, String value) { if (document.hasField(targetField)) { document.appendFieldValue(targetField, value); } else { @@ -103,20 +138,7 @@ public void execute(IngestDocument document) { } else if (oldVal == null) { throw new IllegalArgumentException("field [" + field + "] is null, cannot extract key-value pairs."); } - - String fieldPathPrefix = (targetField == null) ? "" : targetField + "."; - Arrays.stream(oldVal.split(fieldSplit)) - .map((f) -> { - String[] kv = f.split(valueSplit, 2); - if (kv.length != 2) { - throw new IllegalArgumentException("field [" + field + "] does not contain value_split [" + valueSplit + "]"); - } - return kv; - }) - .filter((p) -> - (includeKeys == null || includeKeys.contains(p[0])) && - (excludeKeys == null || excludeKeys.contains(p[0]) == false)) - .forEach((p) -> append(document, fieldPathPrefix + p[0], p[1])); + execution.accept(document, oldVal); } @Override diff --git a/server/src/main/java/org/elasticsearch/ingest/IngestDocument.java b/server/src/main/java/org/elasticsearch/ingest/IngestDocument.java index 2bd842e72b107..aad55e12cefff 100644 --- a/server/src/main/java/org/elasticsearch/ingest/IngestDocument.java +++ b/server/src/main/java/org/elasticsearch/ingest/IngestDocument.java @@ -527,8 +527,7 @@ private static List appendValues(Object maybeList, Object value) { private static void appendValues(List list, Object value) { if (value instanceof List) { - List valueList = (List) value; - valueList.stream().forEach(list::add); + list.addAll((List) value); } else { list.add(value); }