diff options
author | Tor Egge <Tor.Egge@yahoo-inc.com> | 2017-02-06 13:27:47 +0000 |
---|---|---|
committer | Tor Egge <Tor.Egge@yahoo-inc.com> | 2017-02-06 13:27:47 +0000 |
commit | 6e13d7a5a149b4d500130998ac09d78268994d10 (patch) | |
tree | e964f6de47723dedf22322cbaceabdee137ae4e8 /searchcore | |
parent | de18b063dca25956f8696298a1bc422a342655a8 (diff) |
Apply reference attribute updates.
Diffstat (limited to 'searchcore')
4 files changed, 101 insertions, 1 deletions
diff --git a/searchcore/src/tests/applyattrupdates/applyattrupdates.cpp b/searchcore/src/tests/applyattrupdates/applyattrupdates.cpp index 35307317d49..08b21b421f4 100644 --- a/searchcore/src/tests/applyattrupdates/applyattrupdates.cpp +++ b/searchcore/src/tests/applyattrupdates/applyattrupdates.cpp @@ -5,6 +5,7 @@ #include <vespa/document/fieldvalue/floatfieldvalue.h> #include <vespa/document/fieldvalue/intfieldvalue.h> #include <vespa/document/fieldvalue/stringfieldvalue.h> +#include <vespa/document/fieldvalue/referencefieldvalue.h> #include <vespa/document/fieldvalue/weightedsetfieldvalue.h> #include <vespa/document/update/addvalueupdate.h> #include <vespa/document/update/assignvalueupdate.h> @@ -15,6 +16,7 @@ #include <vespa/searchcore/proton/common/attrupdate.h> #include <vespa/searchlib/attribute/attributefactory.h> #include <vespa/searchlib/attribute/attributevector.hpp> +#include <vespa/searchlib/attribute/reference_attribute.h> #include <vespa/vespalib/testkit/testapp.h> #include <vespa/log/log.h> @@ -25,6 +27,7 @@ using namespace document; using search::attribute::BasicType; using search::attribute::Config; using search::attribute::CollectionType; +using search::attribute::ReferenceAttribute; namespace search { @@ -139,6 +142,33 @@ public: int Main(); }; +namespace { + +GlobalId toGid(vespalib::stringref docId) { + return DocumentId(docId).getGlobalId(); +} + +vespalib::string doc1("id:test:testdoc::1"); +vespalib::string doc2("id:test:testdoc::2"); + +ReferenceAttribute &asReferenceAttribute(AttributeVector &vec) +{ + return dynamic_cast<ReferenceAttribute &>(vec); +} + +void assertNoRef(AttributeVector &vec, uint32_t doc) +{ + EXPECT_TRUE(asReferenceAttribute(vec).getReference(doc) == nullptr); +} + +void assertRef(AttributeVector &vec, vespalib::stringref str, uint32_t doc) { + const GlobalId *gid = asReferenceAttribute(vec).getReference(doc); + EXPECT_TRUE(gid != nullptr); + EXPECT_EQUAL(toGid(str), *gid); +} + +} + void Test::requireThatSingleAttributesAreUpdated() { @@ -184,6 +214,26 @@ Test::requireThatSingleAttributesAreUpdated() EXPECT_TRUE(check(vec, 1, Vector<WeightedString>().pb(WeightedString("first")))); EXPECT_TRUE(check(vec, 2, Vector<WeightedString>().pb(WeightedString("")))); } + { + BasicType bt(BasicType::REFERENCE); + Config cfg(bt, ct); + AttributePtr vec = AttributeFactory::createAttribute("in1/ref", cfg); + uint32_t startDoc = 0; + uint32_t endDoc = 0; + EXPECT_TRUE(vec->addDocs(startDoc, endDoc, 3)); + EXPECT_EQUAL(0u, startDoc); + EXPECT_EQUAL(2u, endDoc); + for (uint32_t docId = 0; docId < 3; ++docId) { + asReferenceAttribute(*vec).update(docId, toGid(doc1)); + } + vec->commit(); + applyValueUpdate(*vec, 0, AssignValueUpdate(ReferenceFieldValue(dynamic_cast<const ReferenceDataType &>(_docType->getField("ref").getDataType()), DocumentId(doc2)))); + applyValueUpdate(*vec, 2, ClearValueUpdate()); + EXPECT_EQUAL(3u, vec->getNumDocs()); + TEST_DO(assertRef(*vec, doc2, 0)); + TEST_DO(assertRef(*vec, doc1, 1)); + TEST_DO(assertNoRef(*vec, 2)); + } } void diff --git a/searchcore/src/tests/applyattrupdates/doctypes.cfg b/searchcore/src/tests/applyattrupdates/doctypes.cfg index 23cbf06629e..7da997e6cc9 100644 --- a/searchcore/src/tests/applyattrupdates/doctypes.cfg +++ b/searchcore/src/tests/applyattrupdates/doctypes.cfg @@ -118,7 +118,7 @@ documenttype[0].datatype[6].sstruct.compression.type NONE documenttype[0].datatype[6].sstruct.compression.level 0 documenttype[0].datatype[6].sstruct.compression.threshold 90 documenttype[0].datatype[6].sstruct.compression.minsize 0 -documenttype[0].datatype[6].sstruct.field[9] +documenttype[0].datatype[6].sstruct.field[10] documenttype[0].datatype[6].sstruct.field[0].name "afloat" documenttype[0].datatype[6].sstruct.field[0].id 401182245 documenttype[0].datatype[6].sstruct.field[0].id_v6 303812879 @@ -155,6 +155,10 @@ documenttype[0].datatype[6].sstruct.field[8].name "wsstring" documenttype[0].datatype[6].sstruct.field[8].id 981031285 documenttype[0].datatype[6].sstruct.field[8].id_v6 682978193 documenttype[0].datatype[6].sstruct.field[8].datatype 202 +documenttype[0].datatype[6].sstruct.field[9].name "ref" +documenttype[0].datatype[6].sstruct.field[9].id 981031286 +documenttype[0].datatype[6].sstruct.field[9].id_v6 682978194 +documenttype[0].datatype[6].sstruct.field[9].datatype -1895788438 documenttype[0].datatype[7].id 1878320748 documenttype[0].datatype[7].type STRUCT documenttype[0].datatype[7].array.element.id 0 @@ -172,3 +176,5 @@ documenttype[0].datatype[7].sstruct.compression.threshold 90 documenttype[0].datatype[7].sstruct.compression.minsize 0 documenttype[0].datatype[7].sstruct.field[0] documenttype[0].annotationtype[0] +documenttype[0].referencetype[0].id -1895788438 +documenttype[0].referencetype[0].target_type_id -1175657560 diff --git a/searchcore/src/vespa/searchcore/proton/common/attrupdate.cpp b/searchcore/src/vespa/searchcore/proton/common/attrupdate.cpp index bcc24101019..2068ba3fb20 100644 --- a/searchcore/src/vespa/searchcore/proton/common/attrupdate.cpp +++ b/searchcore/src/vespa/searchcore/proton/common/attrupdate.cpp @@ -6,6 +6,7 @@ #include <vespa/document/fieldvalue/weightedsetfieldvalue.h> #include <vespa/document/fieldvalue/literalfieldvalue.h> #include <vespa/document/fieldvalue/tensorfieldvalue.h> +#include <vespa/document/fieldvalue/referencefieldvalue.h> #include <vespa/document/update/assignvalueupdate.h> #include <vespa/document/update/addvalueupdate.h> #include <vespa/document/update/removevalueupdate.h> @@ -15,6 +16,7 @@ #include <vespa/document/base/forcelink.h> #include <vespa/searchlib/common/base.h> #include <vespa/searchlib/tensor/tensor_attribute.h> +#include <vespa/searchlib/attribute/reference_attribute.h> #include <vespa/searchlib/attribute/attributevector.hpp> #include <vespa/searchlib/attribute/changevector.hpp> @@ -25,6 +27,7 @@ LOG_SETUP(".attrupdate"); using namespace document; using vespalib::make_string; using search::tensor::TensorAttribute; +using search::attribute::ReferenceAttribute; namespace { std::string toString(const FieldUpdate & update) { @@ -213,6 +216,24 @@ void AttrUpdate::handleUpdate(TensorAttribute &vec, uint32_t lid, const ValueUpd } } +template <> +void AttrUpdate::handleUpdate(ReferenceAttribute &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 tensor attribute %s", + upd.getClass().name(), vec.getName().c_str()); + } +} + void AttrUpdate::handleUpdate(AttributeVector & vec, uint32_t lid, const FieldUpdate & fUpdate) { @@ -243,6 +264,8 @@ AttrUpdate::handleUpdate(AttributeVector & vec, uint32_t lid, const FieldUpdate handleUpdate(static_cast<PredicateAttribute &>(vec), lid, vUp); } else if (info.inherits(TensorAttribute::classId)) { handleUpdate(static_cast<TensorAttribute &>(vec), lid, vUp); + } else if (info.inherits(ReferenceAttribute::classId)) { + handleUpdate(static_cast<ReferenceAttribute &>(vec), lid, vUp); } else { LOG(warning, "Unsupported attribute vector '%s' (classname=%s)", vec.getName().c_str(), info.name()); return; @@ -267,6 +290,9 @@ AttrUpdate::handleValue(AttributeVector & vec, uint32_t lid, const FieldValue & } else if (rc.inherits(TensorAttribute::classId)) { // TensorAttribute is never multivalue. updateValue(static_cast<TensorAttribute &>(vec), lid, val); + } else if (rc.inherits(ReferenceAttribute::classId)) { + // ReferenceAttribute is never multivalue. + updateValue(static_cast<ReferenceAttribute &>(vec), lid, val); } else { LOG(warning, "Unsupported attribute vector '%s' (classname=%s)", vec.getName().c_str(), rc.name()); return; @@ -433,4 +459,20 @@ void AttrUpdate::updateValue(TensorAttribute &vec, uint32_t lid, const FieldValu } } +void AttrUpdate::updateValue(ReferenceAttribute &vec, uint32_t lid, const FieldValue &val) +{ + if (!val.inherits(ReferenceFieldValue::classId)) { + vec.clearDoc(lid); + throw UpdateException( + make_string("ReferenceAttribute must be updated with " + "ReferenceFieldValues.")); + } + const auto &reffv = static_cast<const ReferenceFieldValue &>(val); + if (reffv.hasValidDocumentId()) { + vec.update(lid, reffv.getDocumentId().getGlobalId()); + } else { + vec.clearDoc(lid); + } +} + } // namespace search diff --git a/searchcore/src/vespa/searchcore/proton/common/attrupdate.h b/searchcore/src/vespa/searchcore/proton/common/attrupdate.h index 60aaffc132b..8e21257bd4d 100644 --- a/searchcore/src/vespa/searchcore/proton/common/attrupdate.h +++ b/searchcore/src/vespa/searchcore/proton/common/attrupdate.h @@ -14,6 +14,7 @@ using document::FieldValue; using document::FieldUpdate; using document::ValueUpdate; namespace tensor { class TensorAttribute; } +namespace attribute { class ReferenceAttribute; } VESPA_DEFINE_EXCEPTION(UpdateException, vespalib::Exception); @@ -43,6 +44,7 @@ private: static void updateValue(StringAttribute & vec, uint32_t lid, const FieldValue & val); 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); }; } |