From 193085b85889095690a24962b66c8e8c267c690e Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Tue, 7 Mar 2023 09:01:11 +0000 Subject: Allow sorting on raw attributes. --- .../attribute/raw_attribute/raw_attribute_test.cpp | 20 ++++++++++++ .../searchlib/attribute/single_raw_attribute.cpp | 36 ++++++++++++++++++++++ .../searchlib/attribute/single_raw_attribute.h | 2 ++ .../src/vespa/searchlib/attribute/stringbase.cpp | 6 ++-- 4 files changed, 60 insertions(+), 4 deletions(-) diff --git a/searchlib/src/tests/attribute/raw_attribute/raw_attribute_test.cpp b/searchlib/src/tests/attribute/raw_attribute/raw_attribute_test.cpp index bc9d361e29a..82e4fd065cf 100644 --- a/searchlib/src/tests/attribute/raw_attribute/raw_attribute_test.cpp +++ b/searchlib/src/tests/attribute/raw_attribute/raw_attribute_test.cpp @@ -69,4 +69,24 @@ TEST_F(RawAttributeTest, can_set_and_clear_value) EXPECT_EQ(empty, get_raw(1)); } +TEST_F(RawAttributeTest, implements_serialize_for_sort) { + vespalib::string long_hello("hello, is there anybody out there"); + vespalib::ConstArrayRef raw_long_hello(long_hello.c_str(), long_hello.size()); + uint8_t buf[8]; + memset(buf, 0, sizeof(buf)); + _attr->addDocs(10); + _attr->commit(); + EXPECT_EQ(0, _attr->serializeForAscendingSort(1, buf, sizeof(buf))); + EXPECT_EQ(0, _attr->serializeForDescendingSort(1, buf, sizeof(buf))); + _raw->set_raw(1, raw_hello); + EXPECT_EQ(5, _attr->serializeForAscendingSort(1, buf, sizeof(buf))); + EXPECT_EQ(0, memcmp("hello", buf, 5)); + EXPECT_EQ(5, _attr->serializeForDescendingSort(1, buf, sizeof(buf))); + uint8_t expected [] = {0xff-'h', 0xff-'e', 0xff-'l', 0xff-'l', 0xff-'o'}; + EXPECT_EQ(0, memcmp(expected, buf, 5)); + _raw->set_raw(1, raw_long_hello); + EXPECT_EQ(-1, _attr->serializeForAscendingSort(1, buf, sizeof(buf))); + EXPECT_EQ(-1, _attr->serializeForDescendingSort(1, buf, sizeof(buf))); +} + GTEST_MAIN_RUN_ALL_TESTS() diff --git a/searchlib/src/vespa/searchlib/attribute/single_raw_attribute.cpp b/searchlib/src/vespa/searchlib/attribute/single_raw_attribute.cpp index 9bd3a81482a..04d99d3a59a 100644 --- a/searchlib/src/vespa/searchlib/attribute/single_raw_attribute.cpp +++ b/searchlib/src/vespa/searchlib/attribute/single_raw_attribute.cpp @@ -167,4 +167,40 @@ SingleRawAttribute::clearDoc(DocId docId) return 0u; } +long +SingleRawAttribute::onSerializeForAscendingSort(DocId doc, void * serTo, long available, const common::BlobConverter * bc) const +{ + auto raw = get_raw(doc); + vespalib::ConstBufferRef buf(raw.data(), raw.size()); + if (bc != nullptr) { + buf = bc->convert(buf); + } + if (available >= (long)buf.size()) { + memcpy(serTo, buf.data(), buf.size()); + } else { + return -1; + } + return buf.size(); +} + +long +SingleRawAttribute::onSerializeForDescendingSort(DocId doc, void * serTo, long available, const common::BlobConverter * bc) const +{ + auto raw = get_raw(doc); + vespalib::ConstBufferRef buf(raw.data(), raw.size()); + if (bc != nullptr) { + buf = bc->convert(buf); + } + if (available >= (long)buf.size()) { + auto *dst = static_cast(serTo); + const auto * src(static_cast(buf.data())); + for (size_t i(0); i < buf.size(); ++i) { + dst[i] = 0xff - src[i]; + } + } else { + return -1; + } + return buf.size(); +} + } diff --git a/searchlib/src/vespa/searchlib/attribute/single_raw_attribute.h b/searchlib/src/vespa/searchlib/attribute/single_raw_attribute.h index 7477b13bc5a..52b81a782b9 100644 --- a/searchlib/src/vespa/searchlib/attribute/single_raw_attribute.h +++ b/searchlib/src/vespa/searchlib/attribute/single_raw_attribute.h @@ -38,6 +38,8 @@ public: vespalib::ConstArrayRef get_raw(DocId docid) const override; void set_raw(DocId docid, vespalib::ConstArrayRef raw); uint32_t clearDoc(DocId docId) override; + long onSerializeForAscendingSort(DocId, void *, long, const common::BlobConverter *) const override; + long onSerializeForDescendingSort(DocId, void *, long, const common::BlobConverter *) const override; }; } diff --git a/searchlib/src/vespa/searchlib/attribute/stringbase.cpp b/searchlib/src/vespa/searchlib/attribute/stringbase.cpp index 22a2eab1111..55c01964502 100644 --- a/searchlib/src/vespa/searchlib/attribute/stringbase.cpp +++ b/searchlib/src/vespa/searchlib/attribute/stringbase.cpp @@ -118,7 +118,6 @@ StringAttribute::get(DocId doc, largeint_t * v, uint32_t sz) const long StringAttribute::onSerializeForAscendingSort(DocId doc, void * serTo, long available, const common::BlobConverter * bc) const { - auto *dst = static_cast(serTo); const char *value(get(doc)); int size = strlen(value) + 1; vespalib::ConstBufferRef buf(value, size); @@ -126,7 +125,7 @@ StringAttribute::onSerializeForAscendingSort(DocId doc, void * serTo, long avail buf = bc->convert(buf); } if (available >= (long)buf.size()) { - memcpy(dst, buf.data(), buf.size()); + memcpy(serTo, buf.data(), buf.size()); } else { return -1; } @@ -136,8 +135,6 @@ StringAttribute::onSerializeForAscendingSort(DocId doc, void * serTo, long avail long StringAttribute::onSerializeForDescendingSort(DocId doc, void * serTo, long available, const common::BlobConverter * bc) const { - (void) bc; - auto *dst = static_cast(serTo); const char *value(get(doc)); int size = strlen(value) + 1; vespalib::ConstBufferRef buf(value, size); @@ -145,6 +142,7 @@ StringAttribute::onSerializeForDescendingSort(DocId doc, void * serTo, long avai buf = bc->convert(buf); } if (available >= (long)buf.size()) { + auto *dst = static_cast(serTo); const auto * src(static_cast(buf.data())); for (size_t i(0); i < buf.size(); ++i) { dst[i] = 0xff - src[i]; -- cgit v1.2.3