summaryrefslogtreecommitdiffstats
path: root/searchcore
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@yahoo-inc.com>2017-02-06 13:27:47 +0000
committerTor Egge <Tor.Egge@yahoo-inc.com>2017-02-06 13:27:47 +0000
commit6e13d7a5a149b4d500130998ac09d78268994d10 (patch)
treee964f6de47723dedf22322cbaceabdee137ae4e8 /searchcore
parentde18b063dca25956f8696298a1bc422a342655a8 (diff)
Apply reference attribute updates.
Diffstat (limited to 'searchcore')
-rw-r--r--searchcore/src/tests/applyattrupdates/applyattrupdates.cpp50
-rw-r--r--searchcore/src/tests/applyattrupdates/doctypes.cfg8
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/attrupdate.cpp42
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/attrupdate.h2
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);
};
}