From 8f2829cf24a5c2baebecfbe7749cb12a67a52f2b Mon Sep 17 00:00:00 2001 From: Tor Egge Date: Thu, 5 Dec 2024 12:03:36 +0100 Subject: [PATCH] Implement getEnum for reference attribute. --- .../reference_attribute_test.cpp | 19 +++++++++++++++++++ .../attribute/reference_attribute.cpp | 10 +++++++++- .../searchlib/attribute/reference_attribute.h | 1 + 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/searchlib/src/tests/attribute/reference_attribute/reference_attribute_test.cpp b/searchlib/src/tests/attribute/reference_attribute/reference_attribute_test.cpp index a6df61e5bca7..8b4860288a96 100644 --- a/searchlib/src/tests/attribute/reference_attribute/reference_attribute_test.cpp +++ b/searchlib/src/tests/attribute/reference_attribute/reference_attribute_test.cpp @@ -123,6 +123,8 @@ struct ReferenceAttributeTest : public ::testing::Test { return _attr->getReference(doc); } + auto get_enum(uint32_t doc) { return _attr->getEnum(doc); } + void set(uint32_t doc, const GlobalId &gid) { _attr->update(doc, gid); } @@ -467,6 +469,23 @@ TEST_F(ReferenceAttributeTest, unique_gids_are_tracked) EXPECT_EQ(0u, getUniqueGids()); } +TEST_F(ReferenceAttributeTest, getEnum_returns_same_value_for_same_reference) +{ + ensureDocIdLimit(7); + set(1, toGid(doc1)); + set(2, toGid(doc2)); + set(4, toGid(doc1)); + set(5, toGid(doc2)); + commit(); + EXPECT_EQ(get_enum(1), get_enum(4)); + EXPECT_EQ(get_enum(2), get_enum(5)); + EXPECT_EQ(get_enum(3), get_enum(6)); + EXPECT_EQ(get_enum(3), get_enum(7)); + EXPECT_NE(get_enum(1), get_enum(2)); + EXPECT_NE(get_enum(1), get_enum(3)); + EXPECT_NE(get_enum(2), get_enum(3)); +} + struct ReferenceAttributeSearchTest : public ReferenceAttributeTest { constexpr static uint32_t doc_id_limit = 6; diff --git a/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp b/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp index accd541cff65..ba5d374a225f 100644 --- a/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp +++ b/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp @@ -52,7 +52,6 @@ ReferenceAttribute::ReferenceAttribute(const std::string_view baseFileName, cons _gidToLidMapperFactory(), _referenceMappings(getGenerationHolder(), getCommittedDocIdLimitRef(), get_initial_alloc()) { - //TODO this is not safe without implementing getEnum setEnum(true); } @@ -298,6 +297,15 @@ ReferenceAttribute::getReference(DocId doc) const } } +IAttributeVector::EnumHandle +ReferenceAttribute::getEnum(DocId doc) const +{ + if (doc >= getCommittedDocIdLimit()) [[unlikely]] { + return EntryRef().ref(); + } + return _indices.acquire_elem_ref(doc).load_acquire().ref(); +} + bool ReferenceAttribute::consider_compact_values(const CompactionStrategy &compactionStrategy) { diff --git a/searchlib/src/vespa/searchlib/attribute/reference_attribute.h b/searchlib/src/vespa/searchlib/attribute/reference_attribute.h index 33c7aec028d2..c75e8be04ffa 100644 --- a/searchlib/src/vespa/searchlib/attribute/reference_attribute.h +++ b/searchlib/src/vespa/searchlib/attribute/reference_attribute.h @@ -75,6 +75,7 @@ class ReferenceAttribute : public NotImplementedAttribute uint32_t clearDoc(DocId doc) override; void update(DocId doc, const GlobalId &gid); const Reference *getReference(DocId doc) const; + EnumHandle getEnum(DocId doc) const override; void setGidToLidMapperFactory(std::shared_ptr gidToLidMapperFactory); std::shared_ptr getGidToLidMapperFactory() const { return _gidToLidMapperFactory; } TargetLids getTargetLids() const { return _referenceMappings.getTargetLids(); }