aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@vespa.ai>2024-03-31 16:05:43 +0200
committerJon Bratseth <bratseth@vespa.ai>2024-03-31 16:05:43 +0200
commita3761f8fb2e72f3185011809fe21442cbe9378c1 (patch)
treeb6a7aee55cc35b5fe9e530a7ed540b16069cc908
parent8143ac9b4acc09a99887ec29ddb438094b46f56f (diff)
Support values cached during execution of a script
-rw-r--r--config-model/src/main/java/com/yahoo/schema/derived/IndexingScript.java10
-rw-r--r--indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ExecutionContext.java14
-rw-r--r--indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ScriptTestCase.java62
3 files changed, 79 insertions, 7 deletions
diff --git a/config-model/src/main/java/com/yahoo/schema/derived/IndexingScript.java b/config-model/src/main/java/com/yahoo/schema/derived/IndexingScript.java
index 60d27c617f1..39879f2bed7 100644
--- a/config-model/src/main/java/com/yahoo/schema/derived/IndexingScript.java
+++ b/config-model/src/main/java/com/yahoo/schema/derived/IndexingScript.java
@@ -30,7 +30,7 @@ import java.util.List;
import java.util.Set;
/**
- * An indexing language script derived from a search definition. An indexing script contains a set of indexing
+ * An indexing language script derived from a schema. An indexing script contains a set of indexing
* statements, organized in a composite structure of indexing code snippets.
*
* @author bratseth
@@ -62,12 +62,8 @@ public final class IndexingScript extends Derived {
if (field.hasFullIndexingDocprocRights())
docFields.add(field.getName());
- if (field.usesStructOrMap() && ! GeoPos.isAnyPos(field)) {
- return; // unsupported
- }
-
- if (fieldsSettingLanguage.size() == 1 && fieldsSettingLanguage.get(0).equals(field))
- return; // Already added
+ if (field.usesStructOrMap() && ! GeoPos.isAnyPos(field)) return; // unsupported
+ if (fieldsSettingLanguage.size() == 1 && fieldsSettingLanguage.get(0).equals(field)) return; // Already added
addExpression(field.getIndexingScript());
}
diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ExecutionContext.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ExecutionContext.java
index 39e8d10facd..1935664cddc 100644
--- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ExecutionContext.java
+++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ExecutionContext.java
@@ -21,6 +21,7 @@ public class ExecutionContext implements FieldTypeAdapter, FieldValueAdapter {
private final FieldValueAdapter adapter;
private FieldValue value;
private Language language;
+ private Map<String, Object> cache = null;
public ExecutionContext() {
this(null);
@@ -118,6 +119,19 @@ public class ExecutionContext implements FieldTypeAdapter, FieldValueAdapter {
return this;
}
+ public void putCachedValue(String key, Object value) {
+ if (cache == null)
+ cache = new HashMap<>();
+ cache.put(key, value);
+ }
+
+ /** Returns a cached value, or null if not present. */
+ public Object getCachedValue(String key) {
+ if (cache == null) return null;
+ return cache.get(key);
+ }
+
+ /** Clears all state in this except the cache. */
public ExecutionContext clear() {
variables.clear();
value = null;
diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ScriptTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ScriptTestCase.java
index 75f852f0331..df7f99d22d2 100644
--- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ScriptTestCase.java
+++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ScriptTestCase.java
@@ -75,6 +75,20 @@ public class ScriptTestCase {
}
@Test
+ public void testCache() {
+ SimpleTestAdapter adapter = new SimpleTestAdapter(new Field("field1", DataType.STRING));
+ var script = newScript(newStatement(new InputExpression("field1"),
+ new PutCacheExpression("myCacheKey", "myCacheValue")),
+ newStatement(new ClearStateExpression()), // inserted by config model
+ newStatement(new InputExpression("field1"),
+ new AssertCacheExpression("myCacheKey", "myCacheValue")));
+ adapter.setValue("field1", new StringFieldValue("foo1"));
+ ExecutionContext context = new ExecutionContext(adapter);
+ script.execute(context);
+ assertEquals("myCacheValue", context.getCachedValue("myCacheKey"));
+ }
+
+ @Test
public void requireThatStatementsProcessingMissingInputsAreSkipped() {
SimpleTestAdapter adapter = new SimpleTestAdapter(new Field("foo", DataType.STRING),
new Field("bar", DataType.STRING));
@@ -155,4 +169,52 @@ public class ScriptTestCase {
}
+ private static class PutCacheExpression extends Expression {
+
+ private final String keyToSet;
+ private final String valueToSet;
+
+ public PutCacheExpression(String keyToSet, String valueToSet) {
+ super(null);
+ this.keyToSet = keyToSet;
+ this.valueToSet = valueToSet;
+ }
+
+ @Override
+ protected void doExecute(ExecutionContext context) {
+ context.putCachedValue(keyToSet, valueToSet);
+ }
+
+ @Override
+ protected void doVerify(VerificationContext context) {}
+
+ @Override
+ public DataType createdOutputType() { return null; }
+
+ }
+
+ private static class AssertCacheExpression extends Expression {
+
+ private final String expectedKey;
+ private final String expectedValue;
+
+ public AssertCacheExpression(String expectedKey, String expectedValue) {
+ super(null);
+ this.expectedKey = expectedKey;
+ this.expectedValue = expectedValue;
+ }
+
+ @Override
+ protected void doExecute(ExecutionContext context) {
+ assertEquals(expectedValue, context.getCachedValue(expectedKey));
+ }
+
+ @Override
+ protected void doVerify(VerificationContext context) {}
+
+ @Override
+ public DataType createdOutputType() { return null; }
+
+ }
+
}