diff options
author | Geir Storli <geirst@yahooinc.com> | 2023-03-16 11:34:20 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-16 11:34:20 +0100 |
commit | 9ec2f1a8888610e961ba4c6894abb096a8373850 (patch) | |
tree | 446089658d64109ad6da4888228d6da1fc4a690a | |
parent | b5d862334ec1eec5430e9454e85180b81f6bf37f (diff) | |
parent | 81b37a03240d6e9e0f810d6cf73c949a3db24a30 (diff) |
Merge pull request #26458 from vespa-engine/toregge/handle-single-raw-attribute-in-attribute-updater
Handle SingleRawAttribute in AttributeUpdater.
4 files changed, 85 insertions, 4 deletions
diff --git a/searchcore/src/tests/proton/common/attribute_updater/attribute_updater_test.cpp b/searchcore/src/tests/proton/common/attribute_updater/attribute_updater_test.cpp index 8c90b189b69..037bf884e6b 100644 --- a/searchcore/src/tests/proton/common/attribute_updater/attribute_updater_test.cpp +++ b/searchcore/src/tests/proton/common/attribute_updater/attribute_updater_test.cpp @@ -3,6 +3,7 @@ #include <vespa/searchcore/proton/common/attribute_updater.h> #include <vespa/searchlib/attribute/attributefactory.h> #include <vespa/searchlib/attribute/reference_attribute.h> +#include <vespa/searchlib/attribute/single_raw_attribute.h> #include <vespa/searchlib/tensor/dense_tensor_attribute.h> #include <vespa/searchlib/tensor/serialized_fast_value_attribute.h> #include <vespa/searchlib/test/weighted_type_test_utils.h> @@ -13,6 +14,7 @@ #include <vespa/document/fieldvalue/bytefieldvalue.h> #include <vespa/document/fieldvalue/floatfieldvalue.h> #include <vespa/document/fieldvalue/intfieldvalue.h> +#include <vespa/document/fieldvalue/rawfieldvalue.h> #include <vespa/document/fieldvalue/referencefieldvalue.h> #include <vespa/document/fieldvalue/stringfieldvalue.h> #include <vespa/document/fieldvalue/tensorfieldvalue.h> @@ -34,6 +36,7 @@ #include <vespa/eval/eval/value.h> #include <vespa/eval/eval/value_codec.h> #include <vespa/vespalib/stllike/hash_map.hpp> +#include <vespa/vespalib/test/insertion_operators.h> #include <vespa/vespalib/testkit/testapp.h> #include <vespa/log/log.h> @@ -49,6 +52,7 @@ using search::attribute::CollectionType; using search::attribute::Config; using search::attribute::Reference; using search::attribute::ReferenceAttribute; +using search::attribute::SingleRawAttribute; using search::tensor::ITensorAttribute; using search::tensor::DenseTensorAttribute; using search::tensor::SerializedFastValueAttribute; @@ -58,6 +62,18 @@ using vespalib::eval::TensorSpec; using vespalib::eval::Value; using vespalib::eval::ValueType; +namespace { + +std::vector<char> as_vector(vespalib::stringref value) { + return {value.data(), value.data() + value.size()}; +} + +std::vector<char> as_vector(vespalib::ConstArrayRef<char> value) { + return {value.data(), value.data() + value.size()}; +} + +} + namespace search { using AttributePtr = AttributeVector::SP; @@ -74,6 +90,7 @@ makeDocumentTypeRepo() .addField("int", DataType::T_INT) .addField("float", DataType::T_FLOAT) .addField("string", DataType::T_STRING) + .addField("raw", DataType::T_RAW) .addField("aint", Array(DataType::T_INT)) .addField("afloat", Array(DataType::T_FLOAT)) .addField("astring", Array(DataType::T_STRING)) @@ -121,6 +138,10 @@ struct Fixture { applyValueUpdate(vec, 3, std::make_unique<ClearValueUpdate>()); applyValueUpdate(vec, 4, std::make_unique<MapValueUpdate>(std::move(copyOfFirst), std::make_unique<ArithmeticValueUpdate>(ArithmeticValueUpdate::Add, 10))); } + + void applyValue(AttributeVector& vec, uint32_t docid, std::unique_ptr<FieldValue> value) { + search::AttributeUpdater::handleValue(vec, docid, *value); + } }; template <typename T, typename VectorType> @@ -173,7 +194,6 @@ check(const AttributePtr &vec, uint32_t docId, const std::vector<T> &values) return true; } - GlobalId toGid(vespalib::stringref docId) { return DocumentId(docId).getGlobalId(); } @@ -254,6 +274,20 @@ TEST_F("require that single attributes are updated", Fixture) TEST_DO(assertRef(*vec, doc1, 1)); TEST_DO(assertNoRef(*vec, 2)); } + { + BasicType bt(BasicType::RAW); + vespalib::string first_backing("first"); + vespalib::ConstArrayRef<char> first(first_backing.data(), first_backing.size()); + AttributePtr vec = create<vespalib::ConstArrayRef<char>, SingleRawAttribute>(4, first, 0, "in1/raw", Config(bt, ct)); + f.applyValueUpdate(*vec, 0, std::make_unique<AssignValueUpdate>(std::make_unique<RawFieldValue>("second"))); + f.applyValueUpdate(*vec, 2, std::make_unique<ClearValueUpdate>()); + f.applyValue(*vec, 3, std::make_unique<RawFieldValue>("third")); + EXPECT_EQUAL(4u, vec->getNumDocs()); + EXPECT_EQUAL(as_vector("second"), as_vector(vec->get_raw(0))); + EXPECT_EQUAL(as_vector("first"), as_vector(vec->get_raw(1))); + EXPECT_EQUAL(as_vector(""), as_vector(vec->get_raw(2))); + EXPECT_EQUAL(as_vector("third"), as_vector(vec->get_raw(3))); + } } TEST_F("require that array attributes are updated", Fixture) diff --git a/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp b/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp index 6a473df6689..ef9750b5f4c 100644 --- a/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp +++ b/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp @@ -5,6 +5,7 @@ #include <vespa/document/fieldvalue/arrayfieldvalue.h> #include <vespa/document/fieldvalue/literalfieldvalue.h> #include <vespa/document/fieldvalue/predicatefieldvalue.h> +#include <vespa/document/fieldvalue/rawfieldvalue.h> #include <vespa/document/fieldvalue/referencefieldvalue.h> #include <vespa/document/fieldvalue/tensorfieldvalue.h> #include <vespa/document/fieldvalue/weightedsetfieldvalue.h> @@ -22,6 +23,7 @@ #include <vespa/searchlib/attribute/changevector.hpp> #include <vespa/searchlib/attribute/predicate_attribute.h> #include <vespa/searchlib/attribute/reference_attribute.h> +#include <vespa/searchlib/attribute/single_raw_attribute.h> #include <vespa/searchlib/tensor/tensor_attribute.h> #include <vespa/vespalib/util/stringfmt.h> #include <vespa/vespalib/util/classname.h> @@ -36,6 +38,7 @@ using vespalib::getClassName; using search::tensor::PrepareResult; using search::tensor::TensorAttribute; using search::attribute::ReferenceAttribute; +using search::attribute::SingleRawAttribute; namespace { std::string toString(const FieldUpdate & update) { @@ -253,6 +256,26 @@ AttributeUpdater::handleUpdate(ReferenceAttribute &vec, uint32_t lid, const Valu } } +template <> +void +AttributeUpdater::handleUpdate(SingleRawAttribute& vec, uint32_t lid, const ValueUpdate& upd) +{ + LOG(spam, "handleUpdate(%s, %u): %s", vec.getName().c_str(), lid, toString(upd).c_str()); + ValueUpdate::ValueUpdateType op = upd.getType(); + assert(!vec.hasMultiValue()); + if (op == ValueUpdate::Assign) { + const AssignValueUpdate &assign(static_cast<const AssignValueUpdate &>(upd)); + if (assign.hasValue()) { + updateValue(vec, lid, assign.getValue()); + } + } else if (op == ValueUpdate::Clear) { + vec.clearDoc(lid); + } else { + LOG(warning, "Unsupported value update operation %s on singlevalue raw attribute %s", + upd.className(), vec.getName().c_str()); + } +} + void AttributeUpdater::handleUpdate(AttributeVector & vec, uint32_t lid, const FieldUpdate & fUpdate) { @@ -284,6 +307,8 @@ AttributeUpdater::handleUpdate(AttributeVector & vec, uint32_t lid, const FieldU handleUpdate(static_cast<TensorAttribute &>(vec), lid, vUp); } else if (vec.isReferenceType()) { handleUpdate(static_cast<ReferenceAttribute &>(vec), lid, vUp); + } else if (vec.is_raw_type()) { + handleUpdate(static_cast<SingleRawAttribute&>(vec), lid, vUp); } else { LOG(warning, "Unsupported attribute vector '%s' (classname=%s)", vec.getName().c_str(), getClassName(vec).c_str()); return; @@ -310,6 +335,9 @@ AttributeUpdater::handleValue(AttributeVector & vec, uint32_t lid, const FieldVa } else if (vec.isReferenceType()) { // ReferenceAttribute is never multivalue. updateValue(static_cast<ReferenceAttribute &>(vec), lid, val); + } else if (vec.is_raw_type()) { + // SingleRawAttribute is never multivalue + updateValue(static_cast<SingleRawAttribute&>(vec), lid, val); } else { LOG(warning, "Unsupported attribute vector '%s' (classname=%s)", vec.getName().c_str(), getClassName(vec).c_str()); return; @@ -499,6 +527,20 @@ AttributeUpdater::updateValue(ReferenceAttribute &vec, uint32_t lid, const Field } } +void +AttributeUpdater::updateValue(SingleRawAttribute& vec, uint32_t lid, const FieldValue& val) +{ + if (!val.isA(FieldValue::Type::RAW)) { + vec.clearDoc(lid); + throw UpdateException( + make_string("SingleRawAttribute must be updated with " + "RawFieldValue, but was '%s'", val.toString(false).c_str())); + } + const auto& raw_fv = static_cast<const RawFieldValue &>(val); + auto raw = raw_fv.getValueRef(); + vec.update(lid, {raw.data(), raw.size()}); +} + namespace { void diff --git a/searchcore/src/vespa/searchcore/proton/common/attribute_updater.h b/searchcore/src/vespa/searchcore/proton/common/attribute_updater.h index 43b5f9e8477..338ec267e7a 100644 --- a/searchcore/src/vespa/searchcore/proton/common/attribute_updater.h +++ b/searchcore/src/vespa/searchcore/proton/common/attribute_updater.h @@ -14,7 +14,10 @@ namespace tensor { class PrepareResult; class TensorAttribute; } -namespace attribute {class ReferenceAttribute; } +namespace attribute { +class ReferenceAttribute; +class SingleRawAttribute; +} VESPA_DEFINE_EXCEPTION(UpdateException, vespalib::Exception); @@ -56,6 +59,7 @@ private: static void updateValue(PredicateAttribute & vec, uint32_t lid, const FieldValue & val); static void updateValue(tensor::TensorAttribute & vec, uint32_t lid, const FieldValue & val); static void updateValue(attribute::ReferenceAttribute & vec, uint32_t lid, const FieldValue & val); + static void updateValue(attribute::SingleRawAttribute& vec, uint32_t lid, const FieldValue& val); }; } diff --git a/searchlib/src/vespa/searchlib/attribute/single_raw_attribute.h b/searchlib/src/vespa/searchlib/attribute/single_raw_attribute.h index d0baaaf91cd..fe7c873c277 100644 --- a/searchlib/src/vespa/searchlib/attribute/single_raw_attribute.h +++ b/searchlib/src/vespa/searchlib/attribute/single_raw_attribute.h @@ -34,11 +34,12 @@ public: bool addDoc(DocId &docId) override; vespalib::ConstArrayRef<char> get_raw(DocId docid) const override; void set_raw(DocId docid, vespalib::ConstArrayRef<char> raw); - void update(DocId docid, vespalib::ConstArrayRef<char> raw) { set_raw(docid, raw); } - void append(DocId docid, vespalib::ConstArrayRef<char> raw, int32_t weight) { + bool update(DocId docid, vespalib::ConstArrayRef<char> raw) { set_raw(docid, raw); return true; } + bool append(DocId docid, vespalib::ConstArrayRef<char> raw, int32_t weight) { (void) docid; (void) raw; (void) weight; + return false; } bool isUndefined(DocId docid) const override; uint32_t clearDoc(DocId docId) override; |