diff options
10 files changed, 49 insertions, 2 deletions
diff --git a/searchcommon/src/vespa/searchcommon/attribute/iattributevector.h b/searchcommon/src/vespa/searchcommon/attribute/iattributevector.h index 22ba5c646ea..f8ab03fdabb 100644 --- a/searchcommon/src/vespa/searchcommon/attribute/iattributevector.h +++ b/searchcommon/src/vespa/searchcommon/attribute/iattributevector.h @@ -241,6 +241,18 @@ public: **/ virtual bool findEnum(const char * value, EnumHandle & e) const = 0; + /** + * Given an enum handle, returns the string it refers to. + * This method will only have effect if @ref getBasicType() returns BasicType::STRING and + * @ref hasEnum() returns true. + * + * Effectively functions as the inverse of @ref findEnum(value, handle) + * + * @param e a valid enum handle + * @return enum string value, or nullptr if attribute type does + * not support enum handle lookups. + */ + virtual const char * getStringFromEnum(EnumHandle e) const = 0; /** * Creates a context for searching this attribute with the given term. diff --git a/searchlib/src/tests/attribute/imported_attribute_vector/imported_attribute_vector_test.cpp b/searchlib/src/tests/attribute/imported_attribute_vector/imported_attribute_vector_test.cpp index 747db9e2527..f855f51af42 100644 --- a/searchlib/src/tests/attribute/imported_attribute_vector/imported_attribute_vector_test.cpp +++ b/searchlib/src/tests/attribute/imported_attribute_vector/imported_attribute_vector_test.cpp @@ -299,6 +299,20 @@ TEST_F("findEnum() returns target vector enum via reference", SingleStringAttrFi EXPECT_EQUAL(expected_handle, actual_handle); } +// Note: assumes that fixture has set up a string enum of value "foo" in target attribute +template <typename FixtureType> +void verify_get_string_from_enum_is_mapped(FixtureType& f) { + EnumHandle handle{}; + ASSERT_TRUE(f.target_attr->findEnum("foo", handle)); + const char* from_enum = f.imported_attr->getStringFromEnum(handle); + ASSERT_TRUE(from_enum != nullptr); + EXPECT_EQUAL(vespalib::string("foo"), vespalib::string(from_enum)); +} + +TEST_F("Single-value getStringFromEnum() returns string enum is mapped to", SingleStringAttrFixture) { + verify_get_string_from_enum_is_mapped(f); +} + TEST_F("hasEnum() is true for enum target attribute vector", SingleStringAttrFixture) { EXPECT_TRUE(f.imported_attr->hasEnum()); } @@ -353,6 +367,10 @@ TEST_F("Multi-valued enum attribute values can be retrieved via reference", Mult assert_multi_value_matches<EnumHandle>(f, DocId(2), as_vector(expected)); } +TEST_F("Multi-value getStringFromEnum() returns string enum is mapped to", MultiStringAttrFixture) { + verify_get_string_from_enum_is_mapped(f); +} + TEST_F("getValueCount() is equal to stored values for mapped multi value attribute", MultiStringAttrFixture) { EXPECT_EQUAL(f.doc7_values.size(), f.imported_attr->getValueCount(DocId(4))); } @@ -402,6 +420,10 @@ TEST_F("Weighted const char attribute values can be retrieved via reference", We assert_multi_value_matches<WeightedConstChar>(f, DocId(3), as_vector(expected), weighted_string_eq); } +TEST_F("Weighted set getStringFromEnum() returns string enum is mapped to", WeightedMultiStringAttrFixture) { + verify_get_string_from_enum_is_mapped(f); +} + // Poor man's function call mock matching struct MockAttributeVector : NotImplementedAttribute { // Mutable is dirty, but funcs are called in a const context and we know diff --git a/searchlib/src/vespa/searchlib/aggregation/grouping.cpp b/searchlib/src/vespa/searchlib/aggregation/grouping.cpp index 2a80cc02868..5f42fe37386 100644 --- a/searchlib/src/vespa/searchlib/aggregation/grouping.cpp +++ b/searchlib/src/vespa/searchlib/aggregation/grouping.cpp @@ -70,7 +70,7 @@ public: const GroupingLevel & gl = gll[_level]; const ExpressionNode * en = gl.getExpression().getRoot(); const AttributeNode & an = static_cast<const AttributeNode &>(*en); - StringResultNode srn((static_cast<const StringAttribute *>(an.getAttribute()))->getFromEnum(er.getEnum())); + StringResultNode srn(an.getAttribute()->getStringFromEnum(er.getEnum())); group.setId(srn); } tmplevel++; diff --git a/searchlib/src/vespa/searchlib/attribute/attributevector.cpp b/searchlib/src/vespa/searchlib/attribute/attributevector.cpp index ad598ce0c11..938649880c4 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributevector.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attributevector.cpp @@ -542,7 +542,7 @@ int32_t AttributeVector::getWeight(DocId, uint32_t) const { return 1; } bool AttributeVector::findEnum(const char *, EnumHandle &) const { return false; } - +const char * AttributeVector::getStringFromEnum(EnumHandle) const { return nullptr; } AttributeVector::SearchContext::SearchContext(const AttributeVector &attr) : _attr(attr), diff --git a/searchlib/src/vespa/searchlib/attribute/attributevector.h b/searchlib/src/vespa/searchlib/attribute/attributevector.h index 29c9b1a2fb7..d9426822603 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributevector.h +++ b/searchlib/src/vespa/searchlib/attribute/attributevector.h @@ -499,6 +499,7 @@ public: // Implements IAttributeVector bool findEnum(const char *value, EnumHandle &e) const override; + const char * getStringFromEnum(EnumHandle e) const override; ///// Modify API virtual void onCommit() = 0; diff --git a/searchlib/src/vespa/searchlib/attribute/attrvector.h b/searchlib/src/vespa/searchlib/attribute/attrvector.h index ae9887adf32..a6f9a0ebcee 100644 --- a/searchlib/src/vespa/searchlib/attribute/attrvector.h +++ b/searchlib/src/vespa/searchlib/attribute/attrvector.h @@ -147,6 +147,7 @@ private: void onSave(IAttributeSaveTarget & saveTarget) override; bool onLoad() override; const char * getFromEnum(EnumHandle e) const override { return &_buffer[e]; } + const char * getStringFromEnum(EnumHandle e) const override { return &_buffer[e]; } protected: StringDirectAttribute(const vespalib::string & baseFileName, const Config & c); ~StringDirectAttribute(); diff --git a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.cpp b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.cpp index 2aeb2ee0cfe..b6ff442ae94 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.cpp +++ b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.cpp @@ -102,6 +102,10 @@ bool ImportedAttributeVector::findEnum(const char *value, EnumHandle &e) const { return _target_attribute->findEnum(value, e); } +const char * ImportedAttributeVector::getStringFromEnum(EnumHandle e) const { + return _target_attribute->getStringFromEnum(e); +} + std::unique_ptr<ISearchContext> ImportedAttributeVector::createSearchContext(std::unique_ptr<QueryTermSimple> term, const SearchContextParams ¶ms) const { return std::make_unique<ImportedSearchContext>(std::move(term), params, *this); diff --git a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.h b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.h index fe9a0d12d6f..686818c1093 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.h +++ b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.h @@ -50,6 +50,7 @@ public: uint32_t get(DocId docId, WeightedConstChar * buffer, uint32_t sz) const override; uint32_t get(DocId docId, WeightedEnum * buffer, uint32_t sz) const override; bool findEnum(const char * value, EnumHandle & e) const override; + const char * getStringFromEnum(EnumHandle e) const override; std::unique_ptr<ISearchContext> createSearchContext(std::unique_ptr<QueryTermSimple> term, const SearchContextParams ¶ms) const override; const IDocumentWeightAttribute *asDocumentWeightAttribute() const override; diff --git a/searchlib/src/vespa/searchlib/attribute/multistringattribute.h b/searchlib/src/vespa/searchlib/attribute/multistringattribute.h index 7e58ee163df..7edbcedcb2e 100644 --- a/searchlib/src/vespa/searchlib/attribute/multistringattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/multistringattribute.h @@ -71,6 +71,9 @@ public: return this->_enumStore.getValue(indices[0].value()); } } + const char * getStringFromEnum(EnumHandle e) const override { + return this->_enumStore.getValue(e); + } template <typename BufferType> uint32_t getHelper(DocId doc, BufferType * buffer, uint32_t sz) const { WeightedIndexArrayRef indices(this->_mvMapping.get(doc)); diff --git a/searchlib/src/vespa/searchlib/attribute/singlestringattribute.h b/searchlib/src/vespa/searchlib/attribute/singlestringattribute.h index 26346050f0f..227c1d0667c 100644 --- a/searchlib/src/vespa/searchlib/attribute/singlestringattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/singlestringattribute.h @@ -52,6 +52,9 @@ public: const char * get(DocId doc) const override { return this->_enumStore.getValue(this->_enumIndices[doc]); } + const char * getStringFromEnum(EnumHandle e) const override { + return this->_enumStore.getValue(e); + } uint32_t get(DocId doc, vespalib::string * v, uint32_t sz) const override { if (sz > 0) { v[0] = get(doc); |