diff options
author | Geir Storli <geirstorli@yahoo.no> | 2016-08-31 13:44:51 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-08-31 13:44:51 +0200 |
commit | 431961a4f99cfbb394bae5478818333cb8c6f7df (patch) | |
tree | 5097d52d259d8707dc6ff3cf07dec7a1123291d8 /searchlib | |
parent | 179b2b164317d2c6d51d6a7fe881cea6d3fbe8fa (diff) | |
parent | 9a8ec2228b0f4300fc2cefb7cbe05ddbc2636e2f (diff) |
Merge pull request #501 from yahoo/toregge/add-constant-feature
Add constant feature blueprint and constant feature executor.
Diffstat (limited to 'searchlib')
17 files changed, 442 insertions, 87 deletions
diff --git a/searchlib/CMakeLists.txt b/searchlib/CMakeLists.txt index 0ef3b0bac18..c99c3c36bd1 100644 --- a/searchlib/CMakeLists.txt +++ b/searchlib/CMakeLists.txt @@ -111,6 +111,7 @@ vespa_define_module( src/tests/engine/transportserver src/tests/features src/tests/features/beta + src/tests/features/constant src/tests/features/element_completeness src/tests/features/element_similarity_feature src/tests/features/euclidean_distance diff --git a/searchlib/src/tests/features/constant/.gitignore b/searchlib/src/tests/features/constant/.gitignore new file mode 100644 index 00000000000..ec1ff674d9e --- /dev/null +++ b/searchlib/src/tests/features/constant/.gitignore @@ -0,0 +1 @@ +searchlib_constant_test_app diff --git a/searchlib/src/tests/features/constant/CMakeLists.txt b/searchlib/src/tests/features/constant/CMakeLists.txt new file mode 100644 index 00000000000..9a653234a0a --- /dev/null +++ b/searchlib/src/tests/features/constant/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(searchlib_constant_test_app TEST + SOURCES + constant_test.cpp + DEPENDS + searchlib +) +vespa_add_test(NAME searchlib_constant_test_app COMMAND searchlib_constant_test_app) diff --git a/searchlib/src/tests/features/constant/FILES b/searchlib/src/tests/features/constant/FILES new file mode 100644 index 00000000000..5ff67b0b742 --- /dev/null +++ b/searchlib/src/tests/features/constant/FILES @@ -0,0 +1 @@ +constant_test.cpp diff --git a/searchlib/src/tests/features/constant/constant_test.cpp b/searchlib/src/tests/features/constant/constant_test.cpp new file mode 100644 index 00000000000..3fae07f908a --- /dev/null +++ b/searchlib/src/tests/features/constant/constant_test.cpp @@ -0,0 +1,119 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include <vespa/fastos/fastos.h> +#include <vespa/vespalib/testkit/test_kit.h> +#include <vespa/vespalib/eval/function.h> + +#include <vespa/searchlib/features/setup.h> +#include <vespa/searchlib/fef/fef.h> +#include <vespa/searchlib/fef/test/as_tensor.h> +#include <vespa/searchlib/fef/test/ftlib.h> +#include <vespa/searchlib/fef/test/indexenvironment.h> +#include <vespa/vespalib/tensor/default_tensor.h> +#include <vespa/vespalib/tensor/tensor_factory.h> + +using search::feature_t; +using namespace search::fef; +using namespace search::fef::indexproperties; +using namespace search::fef::test; +using namespace search::features; +using vespalib::eval::Function; +using vespalib::eval::Value; +using vespalib::eval::DoubleValue; +using vespalib::eval::TensorValue; +using vespalib::eval::ValueType; +using vespalib::tensor::DenseTensorCells; +using vespalib::tensor::Tensor; +using vespalib::tensor::TensorCells; +using vespalib::tensor::TensorDimensions; +using vespalib::tensor::TensorFactory; + +namespace +{ + +Tensor::UP createTensor(const TensorCells &cells, + const TensorDimensions &dimensions) { + vespalib::tensor::DefaultTensor::builder builder; + return TensorFactory::create(cells, dimensions, builder); +} + +} + +struct ExecFixture +{ + BlueprintFactory factory; + FtFeatureTest test; + ExecFixture(const vespalib::string &feature) + : factory(), + test(factory, feature) + { + setup_search_features(factory); + } + bool setup() { return test.setup(); } + const Tensor &extractTensor() { + const Value::CREF *value = test.resolveObjectFeature(); + ASSERT_TRUE(value != nullptr); + ASSERT_TRUE(value->get().is_tensor()); + return static_cast<const Tensor &>(*value->get().as_tensor()); + } + const Tensor &executeTensor(uint32_t docId = 1) { + test.executeOnly(docId); + return extractTensor(); + } + double extractDouble() { + const Value::CREF *value = test.resolveObjectFeature(); + ASSERT_TRUE(value != nullptr); + ASSERT_TRUE(value->get().is_double()); + return value->get().as_double(); + } + double executeDouble(uint32_t docId = 1) { + test.executeOnly(docId); + return extractDouble(); + } + void addTensor(const vespalib::string &name, + const TensorCells &cells, + const TensorDimensions &dimensions) + { + Tensor::UP tensor = createTensor(cells, dimensions); + ValueType type(tensor->getType().as_value_type()); + test.getIndexEnv().addConstantValue(name, + std::move(type), + std::make_unique<TensorValue>(std::move(tensor))); + } + + void addDouble(const vespalib::string &name, const double value) { + test.getIndexEnv().addConstantValue(name, + ValueType::double_type(), + std::make_unique<DoubleValue>(value)); + } +}; + +TEST_F("require that missing constant is detected", + ExecFixture("constant(foo)")) +{ + EXPECT_TRUE(!f.setup()); +} + + +TEST_F("require that existing tensor constant is detected", + ExecFixture("constant(foo)")) +{ + f.addTensor("foo", + { {{{"x", "a"}}, 3}, + {{{"x", "b"}}, 5}, + {{{"x", "c"}}, 7} }, + { "x" }); + EXPECT_TRUE(f.setup()); + EXPECT_EQUAL(AsTensor("{ {x:b}:5, {x:c}:7, {x:a}:3 }"), f.executeTensor()); +} + + +TEST_F("require that existing double constant is detected", + ExecFixture("constant(foo)")) +{ + f.addDouble("foo", 42.0); + EXPECT_TRUE(f.setup()); + EXPECT_EQUAL(42.0, f.executeDouble()); +} + + +TEST_MAIN() { TEST_RUN_ALL(); } diff --git a/searchlib/src/tests/features/tensor/tensor_test.cpp b/searchlib/src/tests/features/tensor/tensor_test.cpp index 8bcbb5954ff..bcb984c692b 100644 --- a/searchlib/src/tests/features/tensor/tensor_test.cpp +++ b/searchlib/src/tests/features/tensor/tensor_test.cpp @@ -9,16 +9,14 @@ #include <vespa/searchlib/attribute/tensorattribute.h> #include <vespa/searchlib/features/setup.h> #include <vespa/searchlib/fef/fef.h> +#include <vespa/searchlib/fef/test/as_tensor.h> #include <vespa/searchlib/fef/test/ftlib.h> #include <vespa/searchlib/fef/test/indexenvironment.h> #include <vespa/searchlib/fef/test/indexenvironmentbuilder.h> #include <vespa/searchlib/fef/test/queryenvironment.h> -#include <vespa/vespalib/eval/interpreted_function.h> #include <vespa/vespalib/tensor/default_tensor.h> -#include <vespa/vespalib/tensor/default_tensor_engine.h> #include <vespa/vespalib/tensor/serialization/typed_binary_format.h> #include <vespa/vespalib/tensor/tensor_factory.h> -#include <vespa/vespalib/tensor/tensor_mapper.h> using search::feature_t; using namespace search::fef; @@ -29,15 +27,12 @@ using search::AttributeFactory; using search::attribute::TensorAttribute; using search::AttributeVector; using vespalib::eval::Function; -using vespalib::eval::InterpretedFunction; using vespalib::eval::Value; -using vespalib::tensor::DefaultTensorEngine; using vespalib::tensor::DenseTensorCells; using vespalib::tensor::Tensor; using vespalib::tensor::TensorCells; using vespalib::tensor::TensorDimensions; using vespalib::tensor::TensorFactory; -using vespalib::tensor::TensorMapper; using vespalib::tensor::TensorType; typedef search::attribute::Config AVC; @@ -160,41 +155,6 @@ struct ExecFixture } }; -struct AsTensor { - InterpretedFunction ifun; - InterpretedFunction::Context ctx; - const Value *result; - const Tensor *tensor; - explicit AsTensor(const vespalib::string &expr) - : ifun(DefaultTensorEngine::ref(), Function::parse(expr)), ctx(), result(&ifun.eval(ctx)) - { - ASSERT_TRUE(result->is_tensor()); - tensor = static_cast<const Tensor *>(result->as_tensor()); - } - bool operator==(const Tensor &rhs) const { - return tensor->equals(rhs); - } -}; - -struct AsEmptyTensor : public AsTensor { - TensorMapper mapper; - Tensor::UP mappedTensor; - AsEmptyTensor(const vespalib::string &type) - : AsTensor("{ }"), - mapper(TensorType::fromSpec(type)), - mappedTensor(mapper.map(*tensor)) - {} - bool operator==(const Tensor &rhs) const { - return mappedTensor->equals(rhs); - } - -}; - -std::ostream &operator<<(std::ostream &os, const AsTensor &my_tensor) { - os << my_tensor.result->as_tensor(); - return os; -} - TEST_F("require that tensor attribute can be extracted as tensor in attribute feature", ExecFixture("attribute(tensorattr)")) { diff --git a/searchlib/src/tests/features/tensor_from_labels/tensor_from_labels_test.cpp b/searchlib/src/tests/features/tensor_from_labels/tensor_from_labels_test.cpp index b15ffb956ce..8d67ed99fdf 100644 --- a/searchlib/src/tests/features/tensor_from_labels/tensor_from_labels_test.cpp +++ b/searchlib/src/tests/features/tensor_from_labels/tensor_from_labels_test.cpp @@ -2,15 +2,14 @@ #include <vespa/fastos/fastos.h> #include <vespa/vespalib/testkit/test_kit.h> #include <vespa/vespalib/eval/function.h> -#include <vespa/vespalib/eval/interpreted_function.h> #include <vespa/vespalib/tensor/tensor.h> -#include <vespa/vespalib/tensor/default_tensor_engine.h> #include <vespa/searchlib/attribute/attributefactory.h> #include <vespa/searchlib/attribute/attributevector.h> #include <vespa/searchlib/attribute/integerbase.h> #include <vespa/searchlib/attribute/stringbase.h> #include <vespa/searchlib/features/setup.h> +#include <vespa/searchlib/fef/test/as_tensor.h> #include <vespa/searchlib/fef/test/indexenvironment.h> #include <vespa/searchlib/fef/test/indexenvironmentbuilder.h> #include <vespa/searchlib/fef/test/queryenvironment.h> @@ -27,9 +26,7 @@ using search::IntegerAttribute; using search::StringAttribute; using vespalib::eval::Value; using vespalib::eval::Function; -using vespalib::eval::InterpretedFunction; using vespalib::tensor::Tensor; -using vespalib::tensor::DefaultTensorEngine; typedef search::attribute::Config AVC; typedef search::attribute::BasicType AVBT; @@ -126,23 +123,6 @@ struct ExecFixture } }; -struct AsTensor { - InterpretedFunction ifun; - InterpretedFunction::Context ctx; - const Value *result; - explicit AsTensor(const vespalib::string &expr) - : ifun(DefaultTensorEngine::ref(), Function::parse(expr)), ctx(), result(&ifun.eval(ctx)) - { - ASSERT_TRUE(result->is_tensor()); - } - bool operator==(const Tensor &rhs) const { return static_cast<const Tensor &>(*result->as_tensor()).equals(rhs); } -}; - -std::ostream &operator<<(std::ostream &os, const AsTensor &my_tensor) { - os << my_tensor.result->as_tensor(); - return os; -} - // Tests for attribute source: TEST_F("require that array string attribute can be converted to tensor (default dimension)", diff --git a/searchlib/src/tests/features/tensor_from_weighted_set/tensor_from_weighted_set_test.cpp b/searchlib/src/tests/features/tensor_from_weighted_set/tensor_from_weighted_set_test.cpp index 163fd5b5389..a44a0d9fa8f 100644 --- a/searchlib/src/tests/features/tensor_from_weighted_set/tensor_from_weighted_set_test.cpp +++ b/searchlib/src/tests/features/tensor_from_weighted_set/tensor_from_weighted_set_test.cpp @@ -2,15 +2,14 @@ #include <vespa/fastos/fastos.h> #include <vespa/vespalib/testkit/test_kit.h> #include <vespa/vespalib/eval/function.h> -#include <vespa/vespalib/eval/interpreted_function.h> #include <vespa/vespalib/tensor/tensor.h> -#include <vespa/vespalib/tensor/default_tensor_engine.h> #include <vespa/searchlib/attribute/attributefactory.h> #include <vespa/searchlib/attribute/attributevector.h> #include <vespa/searchlib/attribute/integerbase.h> #include <vespa/searchlib/attribute/stringbase.h> #include <vespa/searchlib/features/setup.h> +#include <vespa/searchlib/fef/test/as_tensor.h> #include <vespa/searchlib/fef/test/indexenvironment.h> #include <vespa/searchlib/fef/test/indexenvironmentbuilder.h> #include <vespa/searchlib/fef/test/queryenvironment.h> @@ -27,9 +26,7 @@ using search::IntegerAttribute; using search::StringAttribute; using vespalib::eval::Value; using vespalib::eval::Function; -using vespalib::eval::InterpretedFunction; using vespalib::tensor::Tensor; -using vespalib::tensor::DefaultTensorEngine; typedef search::attribute::Config AVC; typedef search::attribute::BasicType AVBT; @@ -124,23 +121,6 @@ struct ExecFixture } }; -struct AsTensor { - InterpretedFunction ifun; - InterpretedFunction::Context ctx; - const Value *result; - explicit AsTensor(const vespalib::string &expr) - : ifun(DefaultTensorEngine::ref(), Function::parse(expr)), ctx(), result(&ifun.eval(ctx)) - { - ASSERT_TRUE(result->is_tensor()); - } - bool operator==(const Tensor &rhs) const { return static_cast<const Tensor &>(*result->as_tensor()).equals(rhs); } -}; - -std::ostream &operator<<(std::ostream &os, const AsTensor &my_tensor) { - os << my_tensor.result->as_tensor(); - return os; -} - TEST_F("require that weighted set string attribute can be converted to tensor (default dimension)", ExecFixture("tensorFromWeightedSet(attribute(wsstr))")) { diff --git a/searchlib/src/vespa/searchlib/features/CMakeLists.txt b/searchlib/src/vespa/searchlib/features/CMakeLists.txt index c69486505a0..eb8e3ac39d5 100644 --- a/searchlib/src/vespa/searchlib/features/CMakeLists.txt +++ b/searchlib/src/vespa/searchlib/features/CMakeLists.txt @@ -6,6 +6,7 @@ vespa_add_library(searchlib_features OBJECT attributefeature.cpp attributematchfeature.cpp closenessfeature.cpp + constant_feature.cpp debug_attribute_wait.cpp debug_wait.cpp distancefeature.cpp diff --git a/searchlib/src/vespa/searchlib/features/constant_feature.cpp b/searchlib/src/vespa/searchlib/features/constant_feature.cpp new file mode 100644 index 00000000000..e0237587470 --- /dev/null +++ b/searchlib/src/vespa/searchlib/features/constant_feature.cpp @@ -0,0 +1,91 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/fastos/fastos.h> +#include <vespa/log/log.h> +LOG_SETUP(".features.constant_feature"); +#include "constant_feature.h" + +#include <vespa/searchlib/fef/featureexecutor.h> +#include "valuefeature.h" +#include <vespa/vespalib/eval/value_cache/constant_value.h> + +using namespace search::fef; + +namespace search { +namespace features { + +/** + * Feature executor that returns a constant value. + */ +class ConstantFeatureExecutor : public fef::FeatureExecutor +{ +private: + const vespalib::eval::Value &_value; + +public: + ConstantFeatureExecutor(const vespalib::eval::Value &value) + : _value(value) + {} + virtual bool isPure() override { return true; } + virtual void execute(fef::MatchData &data) override { + *data.resolve_object_feature(outputs()[0]) = _value; + } + static FeatureExecutor::LP create(const vespalib::eval::Value &value) { + return FeatureExecutor::LP(new ConstantFeatureExecutor(value)); + } +}; + +ConstantBlueprint::ConstantBlueprint() + : Blueprint("constant"), + _key(), + _value() +{ +} + +ConstantBlueprint::~ConstantBlueprint() +{ +} + +void +ConstantBlueprint::visitDumpFeatures(const IIndexEnvironment &, + IDumpFeatureVisitor &) const +{ +} + +Blueprint::UP +ConstantBlueprint::createInstance() const +{ + return Blueprint::UP(new ConstantBlueprint()); +} + +bool +ConstantBlueprint::setup(const IIndexEnvironment &env, + const ParameterList ¶ms) +{ + _key = params[0].getValue(); + _value = env.getConstantValue(_key); + if (!_value || _value->type().is_error()) { + LOG(error, "Constant '%s' not found", _key.c_str()); + } + FeatureType output_type = _value ? + FeatureType::object(_value->type()) : + FeatureType::number(); + describeOutput("out", "The constant looked up in index environment using the given key.", + output_type); + return (_value && !_value->type().is_error()); +} + +FeatureExecutor::LP +ConstantBlueprint::createExecutor(const IQueryEnvironment &env) const +{ + (void) env; + if (_value) { + return ConstantFeatureExecutor::create(_value->value()); + } else { + // Note: Should not happen, setup() has already failed + return FeatureExecutor::LP(new SingleZeroValueExecutor()); + } +} + +} // namespace features +} // namespace search diff --git a/searchlib/src/vespa/searchlib/features/constant_feature.h b/searchlib/src/vespa/searchlib/features/constant_feature.h new file mode 100644 index 00000000000..3360b072fe3 --- /dev/null +++ b/searchlib/src/vespa/searchlib/features/constant_feature.h @@ -0,0 +1,48 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <vespa/searchlib/fef/blueprint.h> + +namespace vespalib { namespace eval { struct ConstantValue; } } + +namespace search { +namespace features { + +/** + * Implements the blueprint for the constant feature. + * + * An executor of this outputs the value of a named constant. + * This can either be a number or a tensor value. + */ +class ConstantBlueprint : public search::fef::Blueprint { +private: + vespalib::string _key; // 'foo' + std::unique_ptr<vespalib::eval::ConstantValue> _value; + +public: + /** + * Constructs a constant blueprint. + */ + ConstantBlueprint(); + + ~ConstantBlueprint(); + + virtual void visitDumpFeatures(const search::fef::IIndexEnvironment &env, + search::fef::IDumpFeatureVisitor &visitor) const override; + + virtual search::fef::Blueprint::UP createInstance() const override; + + virtual search::fef::ParameterDescriptions getDescriptions() const override { + return search::fef::ParameterDescriptions().desc().string(); + } + + virtual bool setup(const search::fef::IIndexEnvironment &env, + const search::fef::ParameterList ¶ms) override; + + virtual search::fef::FeatureExecutor::LP createExecutor(const search::fef::IQueryEnvironment &env) const override; +}; + +} // namespace features +} // namespace search + diff --git a/searchlib/src/vespa/searchlib/features/setup.cpp b/searchlib/src/vespa/searchlib/features/setup.cpp index 7c98fc8c1ea..f3f99817932 100644 --- a/searchlib/src/vespa/searchlib/features/setup.cpp +++ b/searchlib/src/vespa/searchlib/features/setup.cpp @@ -51,6 +51,7 @@ #include "terminfofeature.h" #include "text_similarity_feature.h" #include "valuefeature.h" +#include "constant_feature.h" using search::fef::Blueprint; @@ -111,6 +112,7 @@ void setup_search_features(fef::IBlueprintRegistry & registry) registry.addPrototype(Blueprint::SP(new ReverseProximityBlueprint())); registry.addPrototype(Blueprint::SP(new TermEditDistanceBlueprint())); registry.addPrototype(Blueprint::SP(new TermFieldMdBlueprint())); + registry.addPrototype(std::make_shared<ConstantBlueprint>()); } } // namespace features diff --git a/searchlib/src/vespa/searchlib/fef/test/CMakeLists.txt b/searchlib/src/vespa/searchlib/fef/test/CMakeLists.txt index dd9ea8828c9..c24d1906873 100644 --- a/searchlib/src/vespa/searchlib/fef/test/CMakeLists.txt +++ b/searchlib/src/vespa/searchlib/fef/test/CMakeLists.txt @@ -1,6 +1,7 @@ # Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. vespa_add_library(searchlib_fef_test OBJECT SOURCES + as_tensor.cpp dummy_dependency_handler.cpp featuretest.cpp ftlib.cpp diff --git a/searchlib/src/vespa/searchlib/fef/test/as_tensor.cpp b/searchlib/src/vespa/searchlib/fef/test/as_tensor.cpp new file mode 100644 index 00000000000..f71973469fb --- /dev/null +++ b/searchlib/src/vespa/searchlib/fef/test/as_tensor.cpp @@ -0,0 +1,57 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/fastos/fastos.h> +#include "as_tensor.h" +#include <vespa/vespalib/testkit/test_kit.h> +#include <vespa/vespalib/tensor/default_tensor_engine.h> +#include <vespa/vespalib/tensor/tensor.h> +#include <vespa/vespalib/tensor/tensor_mapper.h> +#include <vespa/vespalib/eval/function.h> +#include <iostream> + +using vespalib::eval::Function; +using vespalib::tensor::DefaultTensorEngine; +using vespalib::tensor::TensorType; +using vespalib::tensor::TensorMapper; + +namespace search { +namespace fef { +namespace test { + +AsTensor::AsTensor(const vespalib::string &expr) + : ifun(DefaultTensorEngine::ref(), Function::parse(expr)), ctx(), result(&ifun.eval(ctx)) +{ + ASSERT_TRUE(result->is_tensor()); + tensor = static_cast<const Tensor *>(result->as_tensor()); +} + +AsTensor::~AsTensor() +{ +} + +bool AsTensor::operator==(const Tensor &rhs) const { + return tensor->equals(rhs); +}; + +AsEmptyTensor::AsEmptyTensor(const vespalib::string &type) + : AsTensor("{ }"), + mappedTensor(TensorMapper(TensorType::fromSpec(type)).map(*tensor)) +{ +} + +AsEmptyTensor::~AsEmptyTensor() +{ +} + +bool AsEmptyTensor::operator==(const Tensor &rhs) const { + return mappedTensor->equals(rhs); +} + +std::ostream &operator<<(std::ostream &os, const AsTensor &my_tensor) { + os << my_tensor.result->as_tensor(); + return os; +} + +} // search::fef::test +} // search::fef +} // search diff --git a/searchlib/src/vespa/searchlib/fef/test/as_tensor.h b/searchlib/src/vespa/searchlib/fef/test/as_tensor.h new file mode 100644 index 00000000000..3ce930ca5c0 --- /dev/null +++ b/searchlib/src/vespa/searchlib/fef/test/as_tensor.h @@ -0,0 +1,40 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#pragma once + +#include <iosfwd> +#include <vespa/vespalib/eval/interpreted_function.h> + +namespace vespalib { +namespace eval { struct Value; } +namespace tensor { struct Tensor; } +} + +namespace search { +namespace fef { +namespace test { + +struct AsTensor { + using InterpretedFunction = vespalib::eval::InterpretedFunction; + using Value = vespalib::eval::Value; + using Tensor = vespalib::tensor::Tensor; + InterpretedFunction ifun; + InterpretedFunction::Context ctx; + const Value *result; + const Tensor *tensor; + explicit AsTensor(const vespalib::string &expr); + ~AsTensor(); + bool operator==(const Tensor &rhs) const; +}; + +struct AsEmptyTensor : public AsTensor { + std::unique_ptr<Tensor> mappedTensor; + AsEmptyTensor(const vespalib::string &type); + ~AsEmptyTensor(); + bool operator==(const Tensor &rhs) const; +}; + +std::ostream &operator<<(std::ostream &os, const AsTensor &my_tensor); + +} // search::fef::test +} // search::fef +} // search diff --git a/searchlib/src/vespa/searchlib/fef/test/indexenvironment.cpp b/searchlib/src/vespa/searchlib/fef/test/indexenvironment.cpp index fa2e2102311..59903668fdb 100644 --- a/searchlib/src/vespa/searchlib/fef/test/indexenvironment.cpp +++ b/searchlib/src/vespa/searchlib/fef/test/indexenvironment.cpp @@ -11,11 +11,22 @@ namespace search { namespace fef { namespace test { +using vespalib::eval::ValueType; +using vespalib::eval::ErrorValue; + +namespace { + +IndexEnvironment::Constant notFoundError(ValueType::error_type(), + std::make_unique<ErrorValue>()); + +} + IndexEnvironment::IndexEnvironment() : _properties(), _fields(), _attrMan(), - _tableMan() + _tableMan(), + _constants() { } @@ -37,6 +48,29 @@ IndexEnvironment::getFieldByName(const string &name) const return NULL; } + +vespalib::eval::ConstantValue::UP +IndexEnvironment::getConstantValue(const vespalib::string &name) const +{ + auto it = _constants.find(name); + if (it != _constants.end()) { + return std::make_unique<ConstantRef>(it->second); + } else { + return std::make_unique<ConstantRef>(notFoundError); + } +} + +void +IndexEnvironment::addConstantValue(const vespalib::string &name, + vespalib::eval::ValueType type, + std::unique_ptr<vespalib::eval::Value> value) +{ + auto insertRes = _constants.emplace(name, + Constant(std::move(type), + std::move(value))); + assert(insertRes.second); // successful insert +} + } // namespace test } // namespace fef } // namespace search diff --git a/searchlib/src/vespa/searchlib/fef/test/indexenvironment.h b/searchlib/src/vespa/searchlib/fef/test/indexenvironment.h index 98a8349ebef..4edf07b9525 100644 --- a/searchlib/src/vespa/searchlib/fef/test/indexenvironment.h +++ b/searchlib/src/vespa/searchlib/fef/test/indexenvironment.h @@ -20,6 +20,34 @@ namespace test { class IndexEnvironment : public IIndexEnvironment { public: + struct Constant : vespalib::eval::ConstantValue { + vespalib::eval::ValueType _type; + std::unique_ptr<vespalib::eval::Value> _value; + Constant(vespalib::eval::ValueType type, + std::unique_ptr<vespalib::eval::Value> value) + : _type(std::move(type)), _value(std::move(value)) + { } + Constant(Constant &&rhs) + : _type(std::move(rhs._type)), + _value(std::move(rhs._value)) + { + } + const vespalib::eval::ValueType &type() const override { return _type; } + const vespalib::eval::Value &value() const override { return *_value; } + ~Constant() { } + }; + + struct ConstantRef : vespalib::eval::ConstantValue { + const Constant &_value; + ConstantRef(const Constant &value) + : _value(value) + { } + const vespalib::eval::ValueType &type() const override { return _value.type(); } + const vespalib::eval::Value &value() const override { return _value.value(); } + ~ConstantRef() { } + }; + + using ConstantsMap = std::map<vespalib::string, Constant>; /** * Constructs a new index environment. */ @@ -67,9 +95,11 @@ public: /** Returns a reference to the table manager of this. */ TableManager &getTableManager() { return _tableMan; } - virtual vespalib::eval::ConstantValue::UP getConstantValue(const vespalib::string &) const override { - return vespalib::eval::ConstantValue::UP(); - } + virtual vespalib::eval::ConstantValue::UP getConstantValue(const vespalib::string &name) const override; + + void addConstantValue(const vespalib::string &name, + vespalib::eval::ValueType type, + std::unique_ptr<vespalib::eval::Value> value); private: IndexEnvironment(const IndexEnvironment &); // hide @@ -80,6 +110,7 @@ private: std::vector<FieldInfo> _fields; AttributeManager _attrMan; TableManager _tableMan; + ConstantsMap _constants; }; } // namespace test |