diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2017-06-06 15:11:38 +0200 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2017-06-07 09:50:23 +0200 |
commit | ece112cf6aadbf135c92f1d5ddada739b290a118 (patch) | |
tree | 3fb49a56dcfd77e27ee335f5be1f172d3a7975c9 /document | |
parent | 8438c19df2999aed6fd89c470c52a9c04c77dcdc (diff) |
Forward declare XmlOutputStream and FieldValue::IteratorHandler.
Diffstat (limited to 'document')
50 files changed, 702 insertions, 583 deletions
diff --git a/document/src/tests/documenttestcase.cpp b/document/src/tests/documenttestcase.cpp index 3bbd5178055..a9e7b1897b2 100644 --- a/document/src/tests/documenttestcase.cpp +++ b/document/src/tests/documenttestcase.cpp @@ -5,6 +5,7 @@ #include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/document/datatype/annotationreferencedatatype.h> +#include <vespa/document/fieldvalue/iteratorhandler.h> #include <vespa/document/repo/configbuilder.h> #include <vespa/document/serialization/vespadocumentdeserializer.h> #include <vespa/document/serialization/vespadocumentserializer.h> @@ -19,6 +20,8 @@ using namespace document::config_builder; namespace document { +using namespace fieldvalue; + struct DocumentTest : public CppUnit::TestFixture { void testTraversing(); void testFieldPath(); @@ -105,7 +108,7 @@ void DocumentTest::testFieldPath() } } -class Handler : public FieldValue::IteratorHandler { +class Handler : public fieldvalue::IteratorHandler { public: Handler(); ~Handler(); @@ -185,7 +188,7 @@ void DocumentTest::testTraversing() std::string("<P<P<PP[PPP][<PP><PP>]>>>")); } -class VariableIteratorHandler : public FieldValue::IteratorHandler { +class VariableIteratorHandler : public IteratorHandler { public: VariableIteratorHandler(); ~VariableIteratorHandler(); @@ -268,7 +271,7 @@ DocumentTest::testVariables() } -class ModifyIteratorHandler : public FieldValue::IteratorHandler { +class ModifyIteratorHandler : public IteratorHandler { public: ModificationStatus doModify(FieldValue& fv) override { StringFieldValue* sfv = dynamic_cast<StringFieldValue*>(&fv); diff --git a/document/src/tests/fieldpathupdatetestcase.cpp b/document/src/tests/fieldpathupdatetestcase.cpp index 4a23f828921..4311e1059c2 100644 --- a/document/src/tests/fieldpathupdatetestcase.cpp +++ b/document/src/tests/fieldpathupdatetestcase.cpp @@ -1,6 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <vespa/document/base/testdocman.h> #include <vespa/document/fieldvalue/fieldvalues.h> +#include <vespa/document/fieldvalue/iteratorhandler.h> #include <vespa/document/select/node.h> #include <vespa/vespalib/io/fileutil.h> #include <vespa/vdstestlib/cppunit/macros.h> @@ -21,6 +22,8 @@ using namespace document::config_builder; namespace document { +using namespace fieldvalue; + struct FieldPathUpdateTestCase : public CppUnit::TestFixture { DocumentTypeRepo::SP _repo; DocumentType _foobar_type; @@ -259,7 +262,7 @@ void testSerialize(const DocumentTypeRepo& repo, const DocumentUpdate& a) { struct TestFieldPathUpdate : FieldPathUpdate { - struct TestIteratorHandler : FieldValue::IteratorHandler + struct TestIteratorHandler : fieldvalue::IteratorHandler { TestIteratorHandler(std::string& str) : _str(str) {} @@ -288,9 +291,9 @@ struct TestFieldPathUpdate : FieldPathUpdate TestFieldPathUpdate(const TestFieldPathUpdate& other); - std::unique_ptr<FieldValue::IteratorHandler> getIteratorHandler(Document&) const override + std::unique_ptr<IteratorHandler> getIteratorHandler(Document&) const override { - return std::unique_ptr<FieldValue::IteratorHandler>( + return std::unique_ptr<IteratorHandler>( new TestIteratorHandler(_str)); } diff --git a/document/src/vespa/document/fieldvalue/CMakeLists.txt b/document/src/vespa/document/fieldvalue/CMakeLists.txt index 8c76db54d5f..18ea4fc9368 100644 --- a/document/src/vespa/document/fieldvalue/CMakeLists.txt +++ b/document/src/vespa/document/fieldvalue/CMakeLists.txt @@ -10,6 +10,7 @@ vespa_add_library(document_fieldvalues OBJECT fieldvalue.cpp floatfieldvalue.cpp intfieldvalue.cpp + iteratorhandler.cpp literalfieldvalue.cpp longfieldvalue.cpp mapfieldvalue.cpp @@ -22,6 +23,7 @@ vespa_add_library(document_fieldvalues OBJECT structfieldvalue.cpp structuredfieldvalue.cpp tensorfieldvalue.cpp + variablemap.cpp weightedsetfieldvalue.cpp referencefieldvalue.cpp DEPENDS diff --git a/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.cpp b/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.cpp index 9863ee1c18a..cd6d43d2f4d 100644 --- a/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.cpp @@ -1,6 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "annotationreferencefieldvalue.h" +#include <vespa/vespalib/util/xmlstream.h> #include <ostream> using std::ostream; @@ -23,8 +24,7 @@ int AnnotationReferenceFieldValue::compare(const FieldValue &other) const { return (getDataType()->getId() - other.getDataType()->getId()); } -void AnnotationReferenceFieldValue::print(ostream &out, bool, - const string &) const { +void AnnotationReferenceFieldValue::print(ostream &out, bool, const string &) const { out << "AnnotationReferenceFieldValue(n)"; } diff --git a/document/src/vespa/document/fieldvalue/arrayfieldvalue.cpp b/document/src/vespa/document/fieldvalue/arrayfieldvalue.cpp index 8c05c25e651..01df81db69b 100644 --- a/document/src/vespa/document/fieldvalue/arrayfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/arrayfieldvalue.cpp @@ -3,15 +3,23 @@ #include "intfieldvalue.h" #include "stringfieldvalue.h" #include "predicatefieldvalue.h" +#include "iteratorhandler.h" #include <vespa/document/util/serializableexceptions.h> -#include <vespa/vespalib/util/stringfmt.h> +#include <vespa/vespalib/util/polymorphicarrays.h> +#include <vespa/vespalib/util/xmlstream.h> #include <vespa/log/log.h> LOG_SETUP(".document.fieldvalue.array"); +using namespace vespalib::xml; + namespace document { using vespalib::IllegalArgumentException; +using fieldvalue::IndexValue; +using fieldvalue::ModificationStatus; +using fieldvalue::IteratorHandler; +using fieldvalue::VariableMap; IMPLEMENT_IDENTIFIABLE_ABSTRACT(ArrayFieldValue, CollectionFieldValue); @@ -24,7 +32,7 @@ ArrayFieldValue::ArrayFieldValue(const DataType &type) "Cannot generate an array value with non-array type " + type.toString() + ".", VESPA_STRLOC); } - _array = createArray(getNestedType()); + _array.reset(static_cast<IArray *>(createArray(getNestedType()).release())); } ArrayFieldValue::ArrayFieldValue(const ArrayFieldValue& other) @@ -176,14 +184,13 @@ ArrayFieldValue::hasChanged() const return false; } -FieldValue::IteratorHandler::ModificationStatus +fieldvalue::ModificationStatus ArrayFieldValue::iterateSubset(int startPos, int endPos, const vespalib::stringref & variable, PathRange nested, - IteratorHandler& handler) const + fieldvalue::IteratorHandler& handler) const { - FieldValue::IteratorHandler::ModificationStatus - retVal = FieldValue::IteratorHandler::NOT_MODIFIED; + fieldvalue::ModificationStatus retVal = ModificationStatus::NOT_MODIFIED; LOG(spam, "iterateSubset(start=%d, end=%d, variable='%s')", startPos, endPos, variable.c_str()); @@ -192,16 +199,15 @@ ArrayFieldValue::iterateSubset(int startPos, int endPos, for (int i = startPos; i <= endPos && i < static_cast<int>(_array->size()); ++i) { if (!variable.empty()) { - handler.getVariables()[variable] = IteratorHandler::IndexValue(i); + handler.getVariables()[variable] = IndexValue(i); } - FieldValue::IteratorHandler::ModificationStatus - status = array()[i].iterateNested(nested, handler); + ModificationStatus status = array()[i].iterateNested(nested, handler); - if (status == FieldValue::IteratorHandler::REMOVED) { + if (status == ModificationStatus::REMOVED) { indicesToRemove.push_back(i); - retVal = FieldValue::IteratorHandler::MODIFIED; - } else if (status == FieldValue::IteratorHandler::MODIFIED) { + retVal = ModificationStatus::MODIFIED; + } else if (status == ModificationStatus::MODIFIED) { retVal = status; } } @@ -219,7 +225,7 @@ ArrayFieldValue::iterateSubset(int startPos, int endPos, return retVal; } -FieldValue::IteratorHandler::ModificationStatus +fieldvalue::ModificationStatus ArrayFieldValue::onIterateNested(PathRange nested, IteratorHandler & handler) const { IteratorHandler::CollectionScope autoScope(handler, *this); @@ -235,7 +241,7 @@ ArrayFieldValue::onIterateNested(PathRange nested, IteratorHandler & handler) co case FieldPathEntry::VARIABLE: { LOG(spam, "VARIABLE"); - IteratorHandler::VariableMap::iterator iter = handler.getVariables().find(fpe.getVariableName()); + VariableMap::iterator iter = handler.getVariables().find(fpe.getVariableName()); if (iter != handler.getVariables().end()) { int idx = iter->second.index; @@ -259,17 +265,17 @@ ArrayFieldValue::onIterateNested(PathRange nested, IteratorHandler & handler) co } return iterateSubset(0, static_cast<int>(_array->size()) - 1, "", nested, handler); } else { - IteratorHandler::ModificationStatus status = handler.modify(const_cast<ArrayFieldValue&>(*this)); + fieldvalue::ModificationStatus status = handler.modify(const_cast<ArrayFieldValue&>(*this)); - if (status == FieldValue::IteratorHandler::REMOVED) { + if (status == fieldvalue::REMOVED) { return status; } if (handler.handleComplex(*this)) { - if (iterateSubset(0, static_cast<int>(_array->size()) - 1, "", - nested, handler) != FieldValue::IteratorHandler::NOT_MODIFIED) + if (iterateSubset(0, static_cast<int>(_array->size()) - 1, "", nested, handler) + != ModificationStatus::NOT_MODIFIED) { - status = FieldValue::IteratorHandler::MODIFIED; + status = ModificationStatus::MODIFIED; } } diff --git a/document/src/vespa/document/fieldvalue/arrayfieldvalue.h b/document/src/vespa/document/fieldvalue/arrayfieldvalue.h index 33e07e18588..d61acb8605c 100644 --- a/document/src/vespa/document/fieldvalue/arrayfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/arrayfieldvalue.h @@ -14,25 +14,27 @@ #include "collectionfieldvalue.h" #include <vespa/document/datatype/arraydatatype.h> +#include <vespa/vespalib/util/polymorphicarray.h> namespace document { class ArrayFieldValue : public CollectionFieldValue { private: - IArray::UP _array; + using IArray = vespalib::IArrayT<FieldValue>; + std::unique_ptr<IArray> _array; bool addValue(const FieldValue&) override; bool containsValue(const FieldValue& val) const override; bool removeValue(const FieldValue& val) override; - IteratorHandler::ModificationStatus iterateSubset( + fieldvalue::ModificationStatus iterateSubset( int startPos, int endPos, const vespalib::stringref & variable, PathRange nested, - IteratorHandler& handler) const; - IteratorHandler::ModificationStatus onIterateNested(PathRange nested, IteratorHandler & handler) const override; + fieldvalue::IteratorHandler& handler) const; + fieldvalue::ModificationStatus onIterateNested(PathRange nested, fieldvalue::IteratorHandler & handler) const override; public: - typedef IArray::const_iterator const_iterator; - typedef IArray::iterator iterator; - typedef std::unique_ptr<ArrayFieldValue> UP; + using const_iterator = IArray::const_iterator; + using iterator = IArray::iterator; + using UP = std::unique_ptr<ArrayFieldValue>; /** * @param arrayType Type of the array. Must be an ArrayDataType, but does diff --git a/document/src/vespa/document/fieldvalue/document.cpp b/document/src/vespa/document/fieldvalue/document.cpp index 29f487df989..a8336519e16 100644 --- a/document/src/vespa/document/fieldvalue/document.cpp +++ b/document/src/vespa/document/fieldvalue/document.cpp @@ -10,13 +10,14 @@ #include <vespa/document/util/serializableexceptions.h> #include <vespa/document/base/exceptions.h> #include <vespa/document/util/bytebuffer.h> - +#include <vespa/vespalib/util/xmlstream.h> #include <sstream> using vespalib::nbostream; using vespalib::make_string; using vespalib::IllegalArgumentException; using vespalib::IllegalStateException; +using namespace vespalib::xml; namespace document { namespace { diff --git a/document/src/vespa/document/fieldvalue/fieldvalue.cpp b/document/src/vespa/document/fieldvalue/fieldvalue.cpp index 3279eb77a64..c137811514c 100644 --- a/document/src/vespa/document/fieldvalue/fieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/fieldvalue.cpp @@ -10,17 +10,22 @@ #include "doublefieldvalue.h" #include "bytefieldvalue.h" #include "predicatefieldvalue.h" +#include "iteratorhandler.h" #include <vespa/document/util/bytebuffer.h> #include <vespa/document/base/exceptions.h> #include <vespa/document/serialization/vespadocumentserializer.h> #include <vespa/vespalib/objects/nbostream.h> +#include <vespa/vespalib/util/polymorphicarrays.h> +#include <vespa/vespalib/util/xmlstream.h> #include <sstream> using vespalib::FieldBase; using vespalib::nbostream; - +using namespace vespalib::xml; namespace document { +using namespace fieldvalue; + IMPLEMENT_IDENTIFIABLE_ABSTRACT(FieldValue, vespalib::Identifiable); void FieldValue::serialize(nbostream &stream) const { @@ -183,13 +188,13 @@ FieldValue::onGetNestedFieldValue(PathRange nested) const return FieldValue::UP(); } -FieldValue::IteratorHandler::ModificationStatus +ModificationStatus FieldValue::iterateNested(PathRange nested, IteratorHandler & handler) const { return onIterateNested(nested, handler); } -FieldValue::IteratorHandler::ModificationStatus +ModificationStatus FieldValue::onIterateNested(PathRange nested, IteratorHandler & handler) const { if (nested.atEnd()) { @@ -200,78 +205,6 @@ FieldValue::onIterateNested(PathRange nested, IteratorHandler & handler) const } } -FieldValue::IteratorHandler::~IteratorHandler() { } - -bool -FieldValue::IteratorHandler::IndexValue::operator==(const FieldValue::IteratorHandler::IndexValue& other) const { - if (key.get() != NULL) { - if (other.key.get() != NULL && *key == *other.key) { - return true; - } - return false; - } - - return index == other.index; -} - -FieldValue::IteratorHandler::IndexValue::IndexValue(const FieldValue& key_) - : index(-1), - key(FieldValue::CP(key_.clone())) -{ } - -FieldValue::IteratorHandler::IndexValue::~IndexValue() { } - -vespalib::string -FieldValue::IteratorHandler::IndexValue::toString() const { - if (key.get() != NULL) { - return key->toString(); - } else { - return vespalib::make_string("%d", index); - } -} - -void -FieldValue::IteratorHandler::handlePrimitive(uint32_t fid, const FieldValue & fv) { - onPrimitive(fid, Content(fv, getWeight())); -} -bool -FieldValue::IteratorHandler::handleComplex(const FieldValue & fv) { - return onComplex(Content(fv, getWeight())); -} -void -FieldValue::IteratorHandler::handleCollectionStart(const FieldValue & fv) { - onCollectionStart(Content(fv, getWeight())); -} -void -FieldValue::IteratorHandler::handleCollectionEnd(const FieldValue & fv) { - onCollectionEnd(Content(fv, getWeight())); -} -void -FieldValue::IteratorHandler::handleStructStart(const FieldValue & fv) { - onStructStart(Content(fv, getWeight())); -} -void -FieldValue::IteratorHandler::handleStructEnd(const FieldValue & fv) { - onStructEnd(Content(fv, getWeight())); -} - -void -FieldValue::IteratorHandler::onPrimitive(uint32_t fid, const Content & fv) { - (void) fid; - (void) fv; -} - -std::string -FieldValue::IteratorHandler::toString(const VariableMap& vars) { - std::ostringstream out; - out << "[ "; - for (const auto & entry : vars) { - out << entry.first << "=" << entry.second.toString() << " "; - } - out << "]"; - return out.str(); -} - std::string FieldValue::toString(bool verbose, const std::string& indent) const { @@ -295,26 +228,26 @@ private: }; } -FieldValue::IArray::UP +std::unique_ptr<vespalib::IArrayBase> FieldValue::createArray(const DataType & baseType) { switch(baseType.getId()) { case DataType::T_INT: - return IArray::UP(new PrimitiveArrayT<IntFieldValue, FieldValue>()); + return std::make_unique<PrimitiveArrayT<IntFieldValue, FieldValue>>(); case DataType::T_FLOAT: - return IArray::UP(new PrimitiveArrayT<FloatFieldValue, FieldValue>()); + return std::make_unique<PrimitiveArrayT<FloatFieldValue, FieldValue>>(); case DataType::T_STRING: - return IArray::UP(new PrimitiveArrayT<StringFieldValue, FieldValue>()); + return std::make_unique<PrimitiveArrayT<StringFieldValue, FieldValue>>(); case DataType::T_RAW: - return IArray::UP(new PrimitiveArrayT<RawFieldValue, FieldValue>()); + return std::make_unique<PrimitiveArrayT<RawFieldValue, FieldValue>>(); case DataType::T_LONG: - return IArray::UP(new PrimitiveArrayT<LongFieldValue, FieldValue>()); + return std::make_unique<PrimitiveArrayT<LongFieldValue, FieldValue>>(); case DataType::T_DOUBLE: - return IArray::UP(new PrimitiveArrayT<DoubleFieldValue, FieldValue>()); + return std::make_unique<PrimitiveArrayT<DoubleFieldValue, FieldValue>>(); case DataType::T_BYTE: - return IArray::UP(new PrimitiveArrayT<ByteFieldValue, FieldValue>()); + return std::make_unique<PrimitiveArrayT<ByteFieldValue, FieldValue>>(); default: - return IArray::UP(new ComplexArrayT<FieldValue>(FieldValueFactory::UP(new FieldValueFactory(DataType::UP(baseType.clone()))))); + return std::make_unique<ComplexArrayT<FieldValue>>(std::make_unique<FieldValueFactory>(DataType::UP(baseType.clone()))); } } diff --git a/document/src/vespa/document/fieldvalue/fieldvalue.h b/document/src/vespa/document/fieldvalue/fieldvalue.h index 998673ddf8d..a96628514c3 100644 --- a/document/src/vespa/document/fieldvalue/fieldvalue.h +++ b/document/src/vespa/document/fieldvalue/fieldvalue.h @@ -12,12 +12,12 @@ #pragma once #include "fieldvaluevisitor.h" +#include "modificationstatus.h" #include <vespa/document/util/xmlserializable.h> -#include <vespa/vespalib/util/polymorphicarrays.h> +#include <vespa/document/base/fieldpath.h> #include <vespa/vespalib/objects/cloneable.h> #include <vespa/vespalib/objects/identifiable.h> -#include <vespa/document/base/fieldpath.h> -#include <map> +#include <vespa/vespalib/util/polymorphicarraybase.h> namespace vespalib { class nbostream; @@ -25,6 +25,10 @@ namespace vespalib { namespace document { +namespace fieldvalue { + class IteratorHandler; +} + class ByteBuffer; class DataType; @@ -33,8 +37,7 @@ class FieldValue : public vespalib::Identifiable protected: FieldValue(const FieldValue&) = default; FieldValue& operator=(const FieldValue&) = default; - using IArray = vespalib::IArrayT<FieldValue>; - static IArray::UP createArray(const DataType & baseType); + static std::unique_ptr<vespalib::IArrayBase> createArray(const DataType & baseType); public: using PathRange = FieldPath::Range<FieldPath::const_iterator>; @@ -42,110 +45,6 @@ public: using SP = std::shared_ptr<FieldValue>; using CP = vespalib::CloneablePtr<FieldValue>; - class IteratorHandler { - public: - class CollectionScope { - public: - CollectionScope(IteratorHandler& handler, const FieldValue& value) - : _handler(handler), _value(value) - { - _handler.handleCollectionStart(_value); - } - - ~CollectionScope() { - _handler.handleCollectionEnd(_value); - } - private: - IteratorHandler& _handler; - const FieldValue& _value; - }; - - class StructScope { - public: - StructScope(IteratorHandler& handler, const FieldValue& value) - : _handler(handler), _value(value) - { - _handler.handleStructStart(_value); - } - - ~StructScope() { - _handler.handleStructEnd(_value); - } - private: - IteratorHandler& _handler; - const FieldValue& _value; - }; - - class IndexValue { - public: - IndexValue() : index(-1), key() {} - IndexValue(int index_) : index(index_), key() {} - IndexValue(const FieldValue& key_); - ~IndexValue(); - - vespalib::string toString() const; - - bool operator==(const IndexValue& other) const; - - int index; // For array - FieldValue::CP key; // For map/wset - }; - - enum ModificationStatus { - MODIFIED, - REMOVED, - NOT_MODIFIED - }; - - typedef std::map<vespalib::string, IndexValue> VariableMap; - protected: - class Content { - public: - Content(const FieldValue & fv, int weight=1) : _fieldValue(fv), _weight(weight) { } - int getWeight() const { return _weight; } - const FieldValue & getValue() const { return _fieldValue; } - private: - const FieldValue & _fieldValue; - int _weight; - }; - IteratorHandler() : _weight(1) { } - public: - virtual ~IteratorHandler(); - - void handlePrimitive(uint32_t fid, const FieldValue & fv); - - /** - Handles a complex type (struct/array/map etc) that is at the end of the - field path. - @return Return true if you want to recurse into the members. - */ - bool handleComplex(const FieldValue& fv); - void handleCollectionStart(const FieldValue & fv); - void handleCollectionEnd(const FieldValue & fv); - void handleStructStart(const FieldValue & fv); - void handleStructEnd(const FieldValue & fv); - void setWeight(int weight) { _weight = weight; } - ModificationStatus modify(FieldValue& fv) { return doModify(fv); } - - VariableMap& getVariables() { return _variables; } - void setVariables(const VariableMap& vars) { _variables = vars; } - static std::string toString(const VariableMap& vars); - virtual bool createMissingPath() const { return false; } - private: - virtual bool onComplex(const Content& fv) { (void) fv; return true; } - virtual void onPrimitive(uint32_t fid, const Content & fv); - virtual void onCollectionStart(const Content & fv) { (void) fv; } - virtual void onCollectionEnd(const Content & fv) { (void) fv; } - virtual void onStructStart(const Content & fv) { (void) fv; } - virtual void onStructEnd(const Content & fv) { (void) fv; } - virtual ModificationStatus doModify(FieldValue&) { return NOT_MODIFIED; }; - - // Scratchpad to store pass on weight. - int getWeight() const { return _weight; } - int _weight; - VariableMap _variables; - }; - DECLARE_IDENTIFIABLE_ABSTRACT(FieldValue); FieldValue() {} @@ -270,9 +169,9 @@ public: * invocations of the before mentioned methods and the additional * onPrimitive. */ - IteratorHandler::ModificationStatus iterateNested(PathRange nested, IteratorHandler & handler) const; + fieldvalue::ModificationStatus iterateNested(PathRange nested, fieldvalue::IteratorHandler & handler) const; - IteratorHandler::ModificationStatus iterateNested(const FieldPath& fieldPath, IteratorHandler& handler) const { + fieldvalue::ModificationStatus iterateNested(const FieldPath& fieldPath, fieldvalue::IteratorHandler& handler) const { return iterateNested(fieldPath.begin(), fieldPath.end(), handler); } @@ -286,12 +185,12 @@ public: virtual void printXml(XmlOutputStream& out) const = 0; private: - IteratorHandler::ModificationStatus - iterateNested(FieldPath::const_iterator start, FieldPath::const_iterator end, IteratorHandler & handler) const { + fieldvalue::ModificationStatus + iterateNested(FieldPath::const_iterator start, FieldPath::const_iterator end, fieldvalue::IteratorHandler & handler) const { return iterateNested(PathRange(start, end), handler); } virtual FieldValue::UP onGetNestedFieldValue(PathRange nested) const; - virtual IteratorHandler::ModificationStatus onIterateNested(PathRange nested, IteratorHandler & handler) const; + virtual fieldvalue::ModificationStatus onIterateNested(PathRange nested, fieldvalue::IteratorHandler & handler) const; }; std::ostream& operator<<(std::ostream& out, const FieldValue & p); diff --git a/document/src/vespa/document/fieldvalue/iteratorhandler.cpp b/document/src/vespa/document/fieldvalue/iteratorhandler.cpp new file mode 100644 index 00000000000..394979f31cb --- /dev/null +++ b/document/src/vespa/document/fieldvalue/iteratorhandler.cpp @@ -0,0 +1,43 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + + +#include "iteratorhandler.h" + +namespace document::fieldvalue { + +IteratorHandler::~IteratorHandler() { } + + +void +IteratorHandler::handlePrimitive(uint32_t fid, const FieldValue & fv) { + onPrimitive(fid, Content(fv, getWeight())); +} +bool +IteratorHandler::handleComplex(const FieldValue & fv) { + return onComplex(Content(fv, getWeight())); +} +void +IteratorHandler::handleCollectionStart(const FieldValue & fv) { + onCollectionStart(Content(fv, getWeight())); +} +void +IteratorHandler::handleCollectionEnd(const FieldValue & fv) { + onCollectionEnd(Content(fv, getWeight())); +} +void +IteratorHandler::handleStructStart(const FieldValue & fv) { + onStructStart(Content(fv, getWeight())); +} +void +IteratorHandler::handleStructEnd(const FieldValue & fv) { + onStructEnd(Content(fv, getWeight())); +} + +void +IteratorHandler::onPrimitive(uint32_t fid, const Content & fv) { + (void) fid; + (void) fv; +} + +} + diff --git a/document/src/vespa/document/fieldvalue/iteratorhandler.h b/document/src/vespa/document/fieldvalue/iteratorhandler.h new file mode 100644 index 00000000000..8dc98b2107d --- /dev/null +++ b/document/src/vespa/document/fieldvalue/iteratorhandler.h @@ -0,0 +1,99 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include "variablemap.h" +#include "modificationstatus.h" + +namespace document::fieldvalue { + +class IteratorHandler { +public: + class CollectionScope { + public: + CollectionScope(IteratorHandler &handler, const FieldValue &value) + : _handler(handler), _value(value) { + _handler.handleCollectionStart(_value); + } + + ~CollectionScope() { + _handler.handleCollectionEnd(_value); + } + + private: + IteratorHandler &_handler; + const FieldValue &_value; + }; + + class StructScope { + public: + StructScope(IteratorHandler &handler, const FieldValue &value) + : _handler(handler), _value(value) { + _handler.handleStructStart(_value); + } + + ~StructScope() { + _handler.handleStructEnd(_value); + } + + private: + IteratorHandler &_handler; + const FieldValue &_value; + }; + +protected: + class Content { + public: + Content(const FieldValue &fv, int weight = 1) : _fieldValue(fv), _weight(weight) {} + + int getWeight() const { return _weight; } + + const FieldValue &getValue() const { return _fieldValue; } + + private: + const FieldValue &_fieldValue; + int _weight; + }; + + IteratorHandler() : _weight(1) {} + +public: + virtual ~IteratorHandler(); + void handlePrimitive(uint32_t fid, const FieldValue &fv); + + /** + Handles a complex type (struct/array/map etc) that is at the end of the + field path. + @return Return true if you want to recurse into the members. + */ + bool handleComplex(const FieldValue &fv); + void handleCollectionStart(const FieldValue &fv); + void handleCollectionEnd(const FieldValue &fv); + void handleStructStart(const FieldValue &fv); + void handleStructEnd(const FieldValue &fv); + void setWeight(int weight) { _weight = weight; } + ModificationStatus modify(FieldValue &fv) { return doModify(fv); } + fieldvalue::VariableMap &getVariables() { return _variables; } + void setVariables(const fieldvalue::VariableMap &vars) { _variables = vars; } + virtual bool createMissingPath() const { return false; } +private: + virtual bool onComplex(const Content &fv) { + (void) fv; + return true; + } + + virtual void onPrimitive(uint32_t fid, const Content &fv); + virtual void onCollectionStart(const Content &fv) { (void) fv; } + virtual void onCollectionEnd(const Content &fv) { (void) fv; } + virtual void onStructStart(const Content &fv) { (void) fv; } + virtual void onStructEnd(const Content &fv) { (void) fv; } + virtual ModificationStatus doModify(FieldValue &) { return NOT_MODIFIED; }; + + // Scratchpad to store pass on weight. + int getWeight() const { return _weight; } + + int _weight; + fieldvalue::VariableMap _variables; +}; + +} diff --git a/document/src/vespa/document/fieldvalue/literalfieldvalue.cpp b/document/src/vespa/document/fieldvalue/literalfieldvalue.cpp index 4d044219d4c..50c6c901808 100644 --- a/document/src/vespa/document/fieldvalue/literalfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/literalfieldvalue.cpp @@ -1,9 +1,12 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/document/fieldvalue/literalfieldvalue.h> +#include "literalfieldvalue.h" #include <vespa/document/util/stringutil.h> +#include <vespa/vespalib/util/xmlstream.h> #include <sstream> +using namespace vespalib::xml; + namespace document { IMPLEMENT_IDENTIFIABLE_ABSTRACT(LiteralFieldValueB, FieldValue); diff --git a/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp b/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp index 2186ff28f60..a2bc5b97299 100644 --- a/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp @@ -2,12 +2,15 @@ #include "mapfieldvalue.h" #include "weightedsetfieldvalue.h" +#include "iteratorhandler.h" #include <vespa/document/base/exceptions.h> +#include <vespa/vespalib/util/xmlstream.h> #include <vespa/log/log.h> LOG_SETUP(".document.fieldvalue.map"); using vespalib::Identifiable; +using namespace vespalib::xml; /// \todo TODO (was warning): // Find a way to search through internal map without @@ -15,6 +18,8 @@ using vespalib::Identifiable; namespace document { +using namespace fieldvalue; + IMPLEMENT_IDENTIFIABLE_ABSTRACT(MapFieldValue, FieldValue); namespace { @@ -31,8 +36,8 @@ const MapDataType *verifyMapType(const DataType& type) { MapFieldValue::MapFieldValue(const DataType &mapType) : FieldValue(), _type(verifyMapType(mapType)), - _keys(createArray(getMapType().getKeyType())), - _values(createArray(getMapType().getValueType())), + _keys(static_cast<IArray *>(createArray(getMapType().getKeyType()).release())), + _values(static_cast<IArray *>(createArray(getMapType().getValueType()).release())), _altered(true) { } @@ -268,22 +273,22 @@ MapFieldValue::find(const FieldValue& key) } bool MapFieldValue::checkAndRemove(const FieldValue& key, - FieldValue::IteratorHandler::ModificationStatus status, + ModificationStatus status, bool wasModified, std::vector<const FieldValue*>& keysToRemove) const { - if (status == FieldValue::IteratorHandler::REMOVED) { + if (status == ModificationStatus::REMOVED) { LOG(spam, "will remove: %s", key.toString().c_str()); keysToRemove.push_back(&key); return true; - } else if (status == FieldValue::IteratorHandler::MODIFIED) { + } else if (status == ModificationStatus::MODIFIED) { return true; } return wasModified; } -FieldValue::IteratorHandler::ModificationStatus +ModificationStatus MapFieldValue::iterateNestedImpl(PathRange nested, IteratorHandler & handler, const FieldValue& complexFieldValue) const @@ -307,10 +312,9 @@ MapFieldValue::iterateNestedImpl(PathRange nested, wasModified, keysToRemove); } else if (handler.createMissingPath()) { LOG(spam, "creating missing path"); - FieldValue::UP val = - getMapType().getValueType().createFieldValue(); - IteratorHandler::ModificationStatus status = val->iterateNested(nested.next(), handler); - if (status == IteratorHandler::MODIFIED) { + FieldValue::UP val = getMapType().getValueType().createFieldValue(); + ModificationStatus status = val->iterateNested(nested.next(), handler); + if (status == ModificationStatus::MODIFIED) { const_cast<MapFieldValue&>(*this).put(FieldValue::UP(fpe.getLookupKey()->clone()), std::move(val)); return status; } @@ -339,8 +343,7 @@ MapFieldValue::iterateNestedImpl(PathRange nested, case FieldPathEntry::VARIABLE: { LOG(spam, "VARIABLE"); - IteratorHandler::VariableMap::iterator - iter = handler.getVariables().find(fpe.getVariableName()); + VariableMap::iterator iter = handler.getVariables().find(fpe.getVariableName()); if (iter != handler.getVariables().end()) { LOG(spam, "variable key = %s", iter->second.key->toString().c_str()); const_iterator found = find(*iter->second.key); @@ -353,12 +356,9 @@ MapFieldValue::iterateNestedImpl(PathRange nested, PathRange next = nested.next(); for (const_iterator it(begin()), mt(end()); it != mt; it++) { LOG(spam, "key is '%s'", it->first->toString().c_str()); - handler.getVariables()[fpe.getVariableName()] - = IteratorHandler::IndexValue(*it->first); - LOG(spam, "vars at this time = %s", - FieldValue::IteratorHandler::toString(handler.getVariables()).c_str()); - wasModified = checkAndRemove(*it->first, - it->second->iterateNested(next, handler), + handler.getVariables()[fpe.getVariableName()] = IndexValue(*it->first); + LOG(spam, "vars at this time = %s", handler.getVariables().toString().c_str()); + wasModified = checkAndRemove(*it->first, it->second->iterateNested(next, handler), wasModified, keysToRemove); } handler.getVariables().erase(fpe.getVariableName()); @@ -371,8 +371,7 @@ MapFieldValue::iterateNestedImpl(PathRange nested, if (isWSet) { handler.setWeight(static_cast<const IntFieldValue &>(*it->second).getValue()); } - wasModified = checkAndRemove(*it->first, - it->first->iterateNested(nested, handler), + wasModified = checkAndRemove(*it->first, it->first->iterateNested(nested, handler), wasModified, keysToRemove); // Don't iterate over values /*wasModified = checkAndRemove(*it->second, @@ -383,13 +382,12 @@ MapFieldValue::iterateNestedImpl(PathRange nested, } } else { LOG(spam, "at end of field path"); - IteratorHandler::ModificationStatus - status = handler.modify(const_cast<FieldValue&>(complexFieldValue)); + ModificationStatus status = handler.modify(const_cast<FieldValue&>(complexFieldValue)); - if (status == IteratorHandler::REMOVED) { + if (status == ModificationStatus::REMOVED) { LOG(spam, "status = REMOVED"); return status; - } else if (status == IteratorHandler::MODIFIED) { + } else if (status == ModificationStatus::MODIFIED) { LOG(spam, "status = MODIFIED"); wasModified = true; } @@ -419,10 +417,10 @@ MapFieldValue::iterateNestedImpl(PathRange nested, LOG(spam, "erasing map entry with key %s", (*i)->toString().c_str()); const_cast<MapFieldValue&>(*this).erase(**i); } - return wasModified ? IteratorHandler::MODIFIED : IteratorHandler::NOT_MODIFIED; + return wasModified ? ModificationStatus::MODIFIED : ModificationStatus::NOT_MODIFIED; } -FieldValue::IteratorHandler::ModificationStatus +ModificationStatus MapFieldValue::onIterateNested(PathRange nested, IteratorHandler & handler) const { LOG(spam, "iterating over MapFieldValue"); diff --git a/document/src/vespa/document/fieldvalue/mapfieldvalue.h b/document/src/vespa/document/fieldvalue/mapfieldvalue.h index 8b480cbb7f9..edc20fea777 100644 --- a/document/src/vespa/document/fieldvalue/mapfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/mapfieldvalue.h @@ -26,10 +26,10 @@ private: virtual bool containsValue(const FieldValue& fv) const { return contains(fv); } virtual bool removeValue(const FieldValue& fv) { return erase(fv); } bool checkAndRemove(const FieldValue& key, - FieldValue::IteratorHandler::ModificationStatus status, + fieldvalue::ModificationStatus status, bool wasModified, std::vector<const FieldValue*>& keysToRemove) const; - IteratorHandler::ModificationStatus onIterateNested(PathRange nested, IteratorHandler & handler) const override; + fieldvalue::ModificationStatus onIterateNested(PathRange nested, fieldvalue::IteratorHandler & handler) const override; // Utility method to avoid constant explicit casting const MapDataType& getMapType() const { return *_type; } @@ -118,8 +118,8 @@ public: void reserve(size_t sz) { _keys->reserve(sz); _values->reserve(sz); } void resize(size_t sz) { _keys->resize(sz); _values->resize(sz); } - IteratorHandler::ModificationStatus iterateNestedImpl(PathRange nested, IteratorHandler & handler, - const FieldValue& complexFieldValue) const; + fieldvalue::ModificationStatus iterateNestedImpl(PathRange nested, fieldvalue::IteratorHandler & handler, + const FieldValue& complexFieldValue) const; // FieldValue implementation FieldValue& assign(const FieldValue&) override; diff --git a/document/src/vespa/document/fieldvalue/modificationstatus.h b/document/src/vespa/document/fieldvalue/modificationstatus.h new file mode 100644 index 00000000000..344a89338bb --- /dev/null +++ b/document/src/vespa/document/fieldvalue/modificationstatus.h @@ -0,0 +1,13 @@ +// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +namespace document::fieldvalue { + +enum ModificationStatus { + MODIFIED, + REMOVED, + NOT_MODIFIED +}; + +} diff --git a/document/src/vespa/document/fieldvalue/numericfieldvalue.cpp b/document/src/vespa/document/fieldvalue/numericfieldvalue.cpp index 3d39544b3d0..b897a8db930 100644 --- a/document/src/vespa/document/fieldvalue/numericfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/numericfieldvalue.cpp @@ -1,6 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "numericfieldvalue.h" +#include <vespa/vespalib/util/xmlstream.h> namespace document { @@ -9,7 +10,7 @@ IMPLEMENT_IDENTIFIABLE_ABSTRACT(NumericFieldValueBase, FieldValue); void NumericFieldValueBase::printXml(XmlOutputStream& out) const { - out << XmlContent(getAsString()); + out << vespalib::xml::XmlContent(getAsString()); } diff --git a/document/src/vespa/document/fieldvalue/predicatefieldvalue.cpp b/document/src/vespa/document/fieldvalue/predicatefieldvalue.cpp index 8e963f75f5d..a3394d8fcf4 100644 --- a/document/src/vespa/document/fieldvalue/predicatefieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/predicatefieldvalue.cpp @@ -6,9 +6,11 @@ #include <vespa/document/predicate/predicate_printer.h> #include <vespa/vespalib/data/slime/inserter.h> #include <vespa/vespalib/data/slime/slime.h> +#include <vespa/vespalib/util/xmlstream.h> using vespalib::Slime; using vespalib::slime::SlimeInserter; +using namespace vespalib::xml; namespace document { diff --git a/document/src/vespa/document/fieldvalue/rawfieldvalue.cpp b/document/src/vespa/document/fieldvalue/rawfieldvalue.cpp index 96701832b5e..c9950036435 100644 --- a/document/src/vespa/document/fieldvalue/rawfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/rawfieldvalue.cpp @@ -3,6 +3,9 @@ #include "rawfieldvalue.h" #include "literalfieldvalue.hpp" #include <vespa/document/util/stringutil.h> +#include <vespa/vespalib/util/xmlstream.h> + +using namespace vespalib::xml; namespace document { @@ -18,8 +21,7 @@ RawFieldValue::printXml(XmlOutputStream& out) const void RawFieldValue::print(std::ostream& out, bool, const std::string&) const { - StringUtil::printAsHex(out, _value.c_str(), - _value.size()); + StringUtil::printAsHex(out, _value.c_str(), _value.size()); } } // document diff --git a/document/src/vespa/document/fieldvalue/structfieldvalue.cpp b/document/src/vespa/document/fieldvalue/structfieldvalue.cpp index 74805ce3f10..cdfba106c49 100644 --- a/document/src/vespa/document/fieldvalue/structfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/structfieldvalue.cpp @@ -11,6 +11,7 @@ #include <vespa/document/util/serializableexceptions.h> #include <vespa/document/base/exceptions.h> #include <vespa/document/util/bytebuffer.h> +#include <vespa/vespalib/util/xmlstream.h> #include <vespa/log/log.h> LOG_SETUP(".document.structfieldvalue"); @@ -19,6 +20,7 @@ using std::vector; using vespalib::nbostream; using vespalib::nbostream_longlivedbuf; using vespalib::make_string; +using namespace vespalib::xml; namespace document { diff --git a/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp b/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp index 6d77d101ff2..beef80ed2b0 100644 --- a/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp @@ -1,13 +1,19 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "structuredfieldvalue.hpp" -#include "fieldvalues.h" +#include "iteratorhandler.h" +#include "weightedsetfieldvalue.h" +#include "arrayfieldvalue.h" #include <vespa/log/log.h> LOG_SETUP(".document.fieldvalue.structured"); +using vespalib::IllegalArgumentException; + namespace document { +using namespace fieldvalue; + IMPLEMENT_IDENTIFIABLE_ABSTRACT(StructuredFieldValue, FieldValue); StructuredFieldValue::Iterator::Iterator() @@ -59,7 +65,7 @@ void StructuredFieldValue::setFieldValue(const Field & field, const FieldValue & if (!field.getDataType().isValueType(value) && !value.getDataType()->isA(field.getDataType())) { - throw vespalib::IllegalArgumentException( + throw IllegalArgumentException( "Cannot assign value of type " + value.getDataType()->toString() + "with value : '" + value.toString() + "' to field " + field.getName().c_str() + " of type " @@ -81,7 +87,7 @@ StructuredFieldValue::onGetNestedFieldValue(PathRange nested) const return fv; } -FieldValue::IteratorHandler::ModificationStatus +ModificationStatus StructuredFieldValue::onIterateNested(PathRange nested, IteratorHandler & handler) const { IteratorHandler::StructScope autoScope(handler, *this); @@ -93,38 +99,36 @@ StructuredFieldValue::onIterateNested(PathRange nested, IteratorHandler & handle LOG(spam, "fieldRef = %s", fpe.getFieldRef().toString().c_str()); LOG(spam, "fieldValueToSet = %s", fpe.getFieldValueToSet().toString().c_str()); if (exists) { - IteratorHandler::ModificationStatus status = fpe.getFieldValueToSet().iterateNested(nested.next(), handler); - if (status == IteratorHandler::REMOVED) { + ModificationStatus status = fpe.getFieldValueToSet().iterateNested(nested.next(), handler); + if (status == ModificationStatus::REMOVED) { LOG(spam, "field exists, status = REMOVED"); const_cast<StructuredFieldValue&>(*this).remove(fpe.getFieldRef()); - return IteratorHandler::MODIFIED; - } else if (status == IteratorHandler::MODIFIED) { + return ModificationStatus::MODIFIED; + } else if (status == ModificationStatus::MODIFIED) { LOG(spam, "field exists, status = MODIFIED"); const_cast<StructuredFieldValue&>(*this).setFieldValue(fpe.getFieldRef(), fpe.getFieldValueToSet()); - return IteratorHandler::MODIFIED; + return ModificationStatus::MODIFIED; } else { LOG(spam, "field exists, status = %u", status); return status; } } else if (handler.createMissingPath()) { LOG(spam, "createMissingPath is true"); - IteratorHandler::ModificationStatus status - = fpe.getFieldValueToSet().iterateNested(nested.next(), handler); - if (status == IteratorHandler::MODIFIED) { + ModificationStatus status = fpe.getFieldValueToSet().iterateNested(nested.next(), handler); + if (status == ModificationStatus::MODIFIED) { LOG(spam, "field did not exist, status = MODIFIED"); const_cast<StructuredFieldValue&>(*this).setFieldValue(fpe.getFieldRef(), fpe.getFieldValueToSet()); return status; } } LOG(spam, "field did not exist, returning NOT_MODIFIED"); - return IteratorHandler::NOT_MODIFIED; + return ModificationStatus ::NOT_MODIFIED; } else { - throw vespalib::IllegalArgumentException("Illegal field path for struct value"); + throw IllegalArgumentException("Illegal field path for struct value"); } } else { - IteratorHandler::ModificationStatus - status = handler.modify(const_cast<StructuredFieldValue&>(*this)); - if (status == IteratorHandler::REMOVED) { + ModificationStatus status = handler.modify(const_cast<StructuredFieldValue&>(*this)); + if (status == ModificationStatus::REMOVED) { LOG(spam, "field REMOVED"); return status; } @@ -133,11 +137,11 @@ StructuredFieldValue::onIterateNested(PathRange nested, IteratorHandler & handle LOG(spam, "handleComplex"); std::vector<const Field*> fieldsToRemove; for (const_iterator it(begin()), mt(end()); it != mt; ++it) { - IteratorHandler::ModificationStatus currStatus = getValue(it.field())->iterateNested(nested, handler); - if (currStatus == IteratorHandler::REMOVED) { + ModificationStatus currStatus = getValue(it.field())->iterateNested(nested, handler); + if (currStatus == ModificationStatus::REMOVED) { fieldsToRemove.push_back(&it.field()); - status = IteratorHandler::MODIFIED; - } else if (currStatus == IteratorHandler::MODIFIED) { + status = ModificationStatus::MODIFIED; + } else if (currStatus == ModificationStatus::MODIFIED) { status = currStatus; } } diff --git a/document/src/vespa/document/fieldvalue/structuredfieldvalue.h b/document/src/vespa/document/fieldvalue/structuredfieldvalue.h index 4cccbf05de0..eb5912734c5 100644 --- a/document/src/vespa/document/fieldvalue/structuredfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/structuredfieldvalue.h @@ -92,8 +92,8 @@ protected: virtual void setFieldValue(const Field&, FieldValue::UP value) = 0; void setFieldValue(const Field & field, const FieldValue & value); - IteratorHandler::ModificationStatus - onIterateNested(PathRange nested, IteratorHandler & handler) const override; + fieldvalue::ModificationStatus + onIterateNested(PathRange nested, fieldvalue::IteratorHandler & handler) const override; public: DECLARE_IDENTIFIABLE_ABSTRACT(StructuredFieldValue); diff --git a/document/src/vespa/document/fieldvalue/tensorfieldvalue.cpp b/document/src/vespa/document/fieldvalue/tensorfieldvalue.cpp index 93ec934968d..d7d7721e833 100644 --- a/document/src/vespa/document/fieldvalue/tensorfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/tensorfieldvalue.cpp @@ -2,11 +2,13 @@ #include "tensorfieldvalue.h" #include <vespa/document/datatype/datatype.h> +#include <vespa/vespalib/util/xmlstream.h> #include <vespa/eval/tensor/tensor.h> #include <ostream> #include <cassert> using vespalib::tensor::Tensor; +using namespace vespalib::xml; namespace document { diff --git a/document/src/vespa/document/fieldvalue/variablemap.cpp b/document/src/vespa/document/fieldvalue/variablemap.cpp new file mode 100644 index 00000000000..b38b5baeec2 --- /dev/null +++ b/document/src/vespa/document/fieldvalue/variablemap.cpp @@ -0,0 +1,59 @@ +#include "variablemap.h" +#include "fieldvalue.h" +#include <vespa/vespalib/util/stringfmt.h> +#include <vespa/vespalib/stllike/asciistream.h> + +namespace document::fieldvalue { + +IndexValue::IndexValue() : index(-1), key() {} +IndexValue::IndexValue(int index_) : index(index_), key() {} + +bool +IndexValue::operator==(const IndexValue& other) const { + if (key.get() != NULL) { + if (other.key.get() != NULL && *key == *other.key) { + return true; + } + return false; + } + + return index == other.index; +} + +IndexValue::IndexValue(const FieldValue& key_) + : index(-1), + key(FieldValue::CP(key_.clone())) +{ } + +IndexValue::IndexValue(const IndexValue & rhs) = default; +IndexValue & IndexValue::operator = (const IndexValue & rhs) = default; + +IndexValue::~IndexValue() { } + +vespalib::string +IndexValue::toString() const { + if (key.get() != NULL) { + return key->toString(); + } else { + return vespalib::make_string("%d", index); + } +} + +VariableMap::VariableMap() {} +VariableMap::~VariableMap() {} +VariableMap::VariableMap(const VariableMap & rhs) = default; +VariableMap & VariableMap::operator = (const VariableMap & rhs) = default; + +vespalib::string +VariableMap::toString() const { + vespalib::asciistream out; + out << "[ "; + for (const auto & entry : *this) { + out << entry.first << "=" << entry.second.toString() << " "; + } + out << "]"; + return out.str(); +} + +} + diff --git a/document/src/vespa/document/fieldvalue/variablemap.h b/document/src/vespa/document/fieldvalue/variablemap.h new file mode 100644 index 00000000000..06679682e0c --- /dev/null +++ b/document/src/vespa/document/fieldvalue/variablemap.h @@ -0,0 +1,47 @@ +// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <vespa/vespalib/util/memory.h> +#include <vespa/vespalib/stllike/string.h> +#include <map> + +namespace document { + class FieldValue; +} + +namespace document::fieldvalue { + +class IndexValue { +public: + IndexValue(); + IndexValue(int index_); + IndexValue(const FieldValue& key_); + IndexValue(IndexValue && rhs) = default; + IndexValue & operator = (IndexValue && rhs) = default; + IndexValue(const IndexValue & rhs); + IndexValue & operator = (const IndexValue & rhs); + + ~IndexValue(); + + vespalib::string toString() const; + bool operator==(const IndexValue& other) const; + + int index; // For array + vespalib::CloneablePtr<FieldValue> key; // For map/wset +}; + +using VariableMapT = std::map<vespalib::string, IndexValue>; + +class VariableMap : public VariableMapT { +public: + VariableMap(); + VariableMap(VariableMap && rhs) = default; + VariableMap & operator = (VariableMap && rhs) = default; + VariableMap(const VariableMap & rhs); + VariableMap & operator = (const VariableMap & rhs); + ~VariableMap(); + vespalib::string toString() const; +}; + +}
\ No newline at end of file diff --git a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp index 7bf5f5350d3..67e0c8327e6 100644 --- a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp @@ -2,14 +2,20 @@ #include "weightedsetfieldvalue.h" #include <vespa/document/base/exceptions.h> +#include <vespa/vespalib/util/xmlstream.h> #include <ostream> using vespalib::Identifiable; +using vespalib::IllegalArgumentException; +using vespalib::IllegalStateException; +using namespace vespalib::xml; /// \todo TODO (was warning): Find a way to search through internal map without duplicating keys to create shared pointers. namespace document { +using namespace fieldvalue; + IMPLEMENT_IDENTIFIABLE_ABSTRACT(WeightedSetFieldValue, CollectionFieldValue); namespace { @@ -17,9 +23,8 @@ const DataType &getKeyType(const DataType &type) { const WeightedSetDataType *wtype = Identifiable::cast<const WeightedSetDataType *>(&type); if (!wtype) { - throw vespalib::IllegalArgumentException( - "Cannot generate a weighted set value with non-weighted set " - "type " + type.toString() + ".", VESPA_STRLOC); + throw IllegalArgumentException("Cannot generate a weighted set value with non-weighted set " + "type " + type.toString() + ".", VESPA_STRLOC); } return wtype->getNestedType(); } @@ -39,8 +44,7 @@ WeightedSetFieldValue::~WeightedSetFieldValue() { } void WeightedSetFieldValue::verifyKey(const FieldValue & v) { if (!getNestedType().isValueType(v)) { - throw InvalidDataTypeException(*v.getDataType(), getNestedType(), - VESPA_STRLOC); + throw InvalidDataTypeException(*v.getDataType(), getNestedType(), VESPA_STRLOC); } } @@ -92,9 +96,7 @@ WeightedSetFieldValue::increment(const FieldValue& key, int val) } } else { if (it == _map.end()) { - throw vespalib::IllegalStateException("Cannot modify non-existing " - "entry in weightedset without createIfNonExistent set", - VESPA_STRLOC); + throw IllegalStateException("Cannot modify non-existing entry in weightedset without createIfNonExistent set", VESPA_STRLOC); } IntFieldValue& fv = static_cast<IntFieldValue&>(*it->second); fv.setValue(fv.getValue() + val); @@ -203,7 +205,7 @@ WeightedSetFieldValue::find(const FieldValue& key) return _map.find(key); } -FieldValue::IteratorHandler::ModificationStatus +ModificationStatus WeightedSetFieldValue::onIterateNested(PathRange nested, IteratorHandler & handler) const { return _map.iterateNestedImpl(nested, handler, *this); diff --git a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h index 4d6be1fd35a..5de0bf91614 100644 --- a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h @@ -7,9 +7,9 @@ */ #pragma once -#include <vespa/document/fieldvalue/collectionfieldvalue.h> -#include <vespa/document/fieldvalue/mapfieldvalue.h> -#include <vespa/document/fieldvalue/intfieldvalue.h> +#include "collectionfieldvalue.h" +#include "mapfieldvalue.h" +#include "intfieldvalue.h" #include <vespa/document/datatype/weightedsetdatatype.h> #include <map> @@ -33,7 +33,7 @@ private: bool addValue(const FieldValue& fval) override { return add(fval, 1); } bool containsValue(const FieldValue& val) const override; bool removeValue(const FieldValue& val) override; - IteratorHandler::ModificationStatus onIterateNested(PathRange nested, IteratorHandler& handler) const override; + fieldvalue::ModificationStatus onIterateNested(PathRange nested, fieldvalue::IteratorHandler& handler) const override; public: typedef std::unique_ptr<WeightedSetFieldValue> UP; diff --git a/document/src/vespa/document/select/parser.h b/document/src/vespa/document/select/parser.h index 61cc6e05876..b25ec951968 100644 --- a/document/src/vespa/document/select/parser.h +++ b/document/src/vespa/document/select/parser.h @@ -2,10 +2,8 @@ #pragma once -#include <memory> -#include <string> -#include <vespa/document/bucket/bucketidfactory.h> #include "node.h" +#include <vespa/document/bucket/bucketidfactory.h> #include <vespa/vespalib/util/exception.h> #include <vespa/vespalib/util/sync.h> diff --git a/document/src/vespa/document/select/result.h b/document/src/vespa/document/select/result.h index 02d8d61700d..ace3f5f717e 100644 --- a/document/src/vespa/document/select/result.h +++ b/document/src/vespa/document/select/result.h @@ -21,8 +21,7 @@ #include <vespa/document/util/printable.h> -namespace document { -namespace select { +namespace document::select { class Result : public Printable { public: @@ -69,6 +68,4 @@ private: Result& operator=(const Result&) = delete; }; -} // select -} // document - +} diff --git a/document/src/vespa/document/select/resultlist.cpp b/document/src/vespa/document/select/resultlist.cpp index f8224b7a158..2cde06fa2f2 100644 --- a/document/src/vespa/document/select/resultlist.cpp +++ b/document/src/vespa/document/select/resultlist.cpp @@ -15,8 +15,7 @@ ResultList::ResultList(const Result& result) { } void -ResultList::add(const FieldValue::IteratorHandler::VariableMap& variables, - const Result& result) +ResultList::add(const fieldvalue::VariableMap& variables, const Result& result) { _results.push_back(ResultPair(variables, &result)); } @@ -27,8 +26,7 @@ ResultList::print(std::ostream& out, bool, const std::string&) const out << "ResultList("; for (uint32_t i = 0; i < _results.size(); i++) { if (!_results[i].first.empty()) { - out << FieldValue::IteratorHandler::toString(_results[i].first) - << " => "; + out << _results[i].first.toString() << " => "; } out << _results[i].second->toString() << " "; } @@ -66,15 +64,12 @@ ResultList::combineResults() const { bool ResultList::combineVariables( - FieldValue::IteratorHandler::VariableMap& output, - const FieldValue::IteratorHandler::VariableMap& input) const + fieldvalue::VariableMap& output, + const fieldvalue::VariableMap& input) const { // First, verify that all variables are overlapping - for (FieldValue::IteratorHandler::VariableMap::const_iterator iter - = output.begin(); iter != output.end(); iter++) - { - FieldValue::IteratorHandler::VariableMap::const_iterator found( - input.find(iter->first)); + for (fieldvalue::VariableMap::const_iterator iter = output.begin(); iter != output.end(); iter++) { + fieldvalue::VariableMap::const_iterator found(input.find(iter->first)); if (found != input.end()) { if (!(found->second == iter->second)) { @@ -83,11 +78,8 @@ ResultList::combineVariables( } } - for (FieldValue::IteratorHandler::VariableMap::const_iterator iter - = input.begin(); iter != input.end(); iter++) - { - FieldValue::IteratorHandler::VariableMap::const_iterator found( - output.find(iter->first)); + for (fieldvalue::VariableMap::const_iterator iter = input.begin(); iter != input.end(); iter++) { + fieldvalue::VariableMap::const_iterator found(output.find(iter->first)); if (found != output.end()) { if (!(found->second == iter->second)) { return false; @@ -95,9 +87,7 @@ ResultList::combineVariables( } } // Ok, variables are overlapping. Add all variables from input to output. - for (FieldValue::IteratorHandler::VariableMap::const_iterator iter - = input.begin(); iter != input.end(); iter++) - { + for (fieldvalue::VariableMap::const_iterator iter = input.begin(); iter != input.end(); iter++) { output[iter->first] = iter->second; } @@ -112,7 +102,7 @@ ResultList::operator&&(const ResultList& other) const // TODO: optimize for (const auto & it : _results) { for (const auto & it2 : other._results) { - FieldValue::IteratorHandler::VariableMap vars = it.first; + fieldvalue::VariableMap vars = it.first; if (combineVariables(vars, it2.first)) { result.add(vars, *it.second && *it2.second); @@ -131,7 +121,7 @@ ResultList::operator||(const ResultList& other) const // TODO: optimize for (const auto & it : _results) { for (const auto & it2 : other._results) { - FieldValue::IteratorHandler::VariableMap vars = it.first; + fieldvalue::VariableMap vars = it.first; if (combineVariables(vars, it2.first)) { result.add(vars, *it.second || *it2.second); diff --git a/document/src/vespa/document/select/resultlist.h b/document/src/vespa/document/select/resultlist.h index 6a3cc1f78d1..a00419d9196 100644 --- a/document/src/vespa/document/select/resultlist.h +++ b/document/src/vespa/document/select/resultlist.h @@ -1,16 +1,15 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vector> -#include <vespa/document/fieldvalue/fieldvalue.h> #include "result.h" +#include <vector> +#include <vespa/document/fieldvalue/variablemap.h> -namespace document { -namespace select { +namespace document::select { class ResultList : public Printable { public: - typedef FieldValue::IteratorHandler::VariableMap VariableMap; + using VariableMap = fieldvalue::VariableMap; typedef std::pair<VariableMap, const Result*> ResultPair; typedef std::vector<ResultPair> Results; typedef Results::iterator iterator; @@ -49,7 +48,7 @@ public: private: Results _results; - bool combineVariables(VariableMap& output, const FieldValue::IteratorHandler::VariableMap& input) const; + bool combineVariables(VariableMap& output, const VariableMap& input) const; }; inline bool operator==(const ResultList& list, const Result& other) { @@ -61,5 +60,4 @@ inline bool operator!=(const ResultList& list, const Result& other) { } } -} diff --git a/document/src/vespa/document/select/value.cpp b/document/src/vespa/document/select/value.cpp index 7a453fe5cf3..3540935f8c7 100644 --- a/document/src/vespa/document/select/value.cpp +++ b/document/src/vespa/document/select/value.cpp @@ -2,6 +2,7 @@ #include "value.h" #include "operator.h" +#include <vespa/document/fieldvalue/fieldvalue.h> namespace document { namespace select { diff --git a/document/src/vespa/document/select/value.h b/document/src/vespa/document/select/value.h index 15856648985..b26e959ea1d 100644 --- a/document/src/vespa/document/select/value.h +++ b/document/src/vespa/document/select/value.h @@ -1,4 +1,5 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + /** * @class document::select::Value * @ingroup select @@ -190,7 +191,7 @@ inline ResultList FloatValue::operator==(const FloatValue& value) const class ArrayValue : public Value { public: - typedef std::pair<FieldValue::IteratorHandler::VariableMap, Value::SP> VariableValue; + using VariableValue = std::pair<fieldvalue::VariableMap, Value::SP>; ArrayValue(const std::vector<VariableValue>& values); diff --git a/document/src/vespa/document/select/valuenode.cpp b/document/src/vespa/document/select/valuenode.cpp index 96bc46bd54e..f463c0e3288 100644 --- a/document/src/vespa/document/select/valuenode.cpp +++ b/document/src/vespa/document/select/valuenode.cpp @@ -4,6 +4,7 @@ #include "parser.h" #include <vespa/document/base/exceptions.h> #include <vespa/document/fieldvalue/fieldvalues.h> +#include <vespa/document/fieldvalue/iteratorhandler.h> #include <vespa/document/datatype/documenttype.h> #include <vespa/vespalib/util/md5.h> #include <vespa/document/util/stringutil.h> @@ -16,6 +17,7 @@ LOG_SETUP(".document.select.valuenode"); namespace document { + namespace select { namespace { @@ -157,7 +159,6 @@ VariableValueNode::getValue(const Context& context) const { return context.getValue(_value); } - void VariableValueNode::visit(Visitor &visitor) const { @@ -216,82 +217,48 @@ FieldValueNode::extractFieldName(const std::string & fieldExpression) { throw ParsingFailedException("Fatal: could not extract field name from field expression '" + fieldExpression + "'"); } -void -FieldValueNode::initFieldPath(const DocumentType& type) const { - if (_fieldPath.size() == 0) { - FieldPath::UP path(type.buildFieldPath(_fieldExpression)); - if (!path.get()) { - throw FieldNotFoundException( - vespalib::make_string("Could not create field path for doc type: '%s' field: '%s'", - type.toString().c_str(), _fieldExpression.c_str()), - VESPA_STRLOC); - } - _fieldPath = *path; - } -} - -std::unique_ptr<Value> -FieldValueNode::getValue(const Context& context) const -{ - if (context._doc == NULL) { - return std::unique_ptr<Value>(new InvalidValue()); - } - - const Document& doc = *context._doc; - - if (!documentTypeEqualsName(doc.getType(), _doctype)) { - return std::unique_ptr<Value>(new InvalidValue()); - } - try{ - initFieldPath(doc.getType()); +namespace { - IteratorHandler handler; - doc.iterateNested(_fieldPath.getFullRange(), handler); +class IteratorHandler : public fieldvalue::IteratorHandler { +public: + IteratorHandler(); + ~IteratorHandler(); + bool hasSingleValue() const; + std::unique_ptr<Value> getSingleValue(); + const std::vector<ArrayValue::VariableValue> &getValues(); - if (handler.hasSingleValue()) { - return handler.getSingleValue(); - } else { - const std::vector<ArrayValue::VariableValue>& values = handler.getValues(); +private: + std::unique_ptr<Value> _firstValue; + std::vector<ArrayValue::VariableValue> _values; - if (values.size() == 0) { - return std::unique_ptr<Value>(new NullValue()); - } else { - return std::unique_ptr<Value>(new ArrayValue(handler.getValues())); - } - } - } catch (vespalib::IllegalArgumentException& e) { - LOG(warning, "Caught exception while fetching field from document: %s", e.what()); - return std::unique_ptr<Value>(new InvalidValue()); - } catch (FieldNotFoundException& e) { - LOG(warning, "Tried to compare to field %s, not found in document type", _fieldExpression.c_str()); - return std::unique_ptr<Value>(new InvalidValue()); - } -} + void onPrimitive(uint32_t fid, const Content &fv) override; + std::unique_ptr<Value> getInternalValue(const FieldValue &fval) const; +}; -FieldValueNode::IteratorHandler::IteratorHandler() { } -FieldValueNode::IteratorHandler::~IteratorHandler() { } +IteratorHandler::IteratorHandler() { } +IteratorHandler::~IteratorHandler() { } bool -FieldValueNode::IteratorHandler::hasSingleValue() const { +IteratorHandler::hasSingleValue() const { return _firstValue.get() && (_values.size() == 0); } std::unique_ptr<Value> -FieldValueNode::IteratorHandler::getSingleValue() { +IteratorHandler::getSingleValue() { return std::move(_firstValue); } const std::vector<ArrayValue::VariableValue>& -FieldValueNode::IteratorHandler::getValues() { +IteratorHandler::getValues() { if (_firstValue.get()) { - _values.insert(_values.begin(), ArrayValue::VariableValue(FieldValue::IteratorHandler::VariableMap(), Value::SP(_firstValue.release()))); + _values.insert(_values.begin(), ArrayValue::VariableValue(fieldvalue::VariableMap(), Value::SP(_firstValue.release()))); } return _values; } void -FieldValueNode::IteratorHandler::onPrimitive(uint32_t fid, const Content& fv) { +IteratorHandler::onPrimitive(uint32_t fid, const Content& fv) { (void) fid; if (!_firstValue && getVariables().empty()) { _firstValue = getInternalValue(fv.getValue()); @@ -301,7 +268,7 @@ FieldValueNode::IteratorHandler::onPrimitive(uint32_t fid, const Content& fv) { } std::unique_ptr<Value> -FieldValueNode::IteratorHandler::getInternalValue(const FieldValue& fval) const +IteratorHandler::getInternalValue(const FieldValue& fval) const { switch(fval.getClass().id()) { case document::IntFieldValue::classId: @@ -372,10 +339,63 @@ FieldValueNode::IteratorHandler::getInternalValue(const FieldValue& fval) const } } LOG(warning, "Tried to use unsupported datatype %s in field comparison", - fval.getDataType()->toString().c_str()); + fval.getDataType()->toString().c_str()); return std::make_unique<InvalidValue>(); } +} + +void +FieldValueNode::initFieldPath(const DocumentType& type) const { + if (_fieldPath.size() == 0) { + FieldPath::UP path(type.buildFieldPath(_fieldExpression)); + if (!path.get()) { + throw FieldNotFoundException( + vespalib::make_string("Could not create field path for doc type: '%s' field: '%s'", + type.toString().c_str(), _fieldExpression.c_str()), + VESPA_STRLOC); + } + _fieldPath = *path; + } +} + +std::unique_ptr<Value> +FieldValueNode::getValue(const Context& context) const +{ + if (context._doc == NULL) { + return std::unique_ptr<Value>(new InvalidValue()); + } + + const Document& doc = *context._doc; + + if (!documentTypeEqualsName(doc.getType(), _doctype)) { + return std::unique_ptr<Value>(new InvalidValue()); + } + try{ + initFieldPath(doc.getType()); + + IteratorHandler handler; + doc.iterateNested(_fieldPath.getFullRange(), handler); + + if (handler.hasSingleValue()) { + return handler.getSingleValue(); + } else { + const std::vector<ArrayValue::VariableValue>& values = handler.getValues(); + + if (values.size() == 0) { + return std::unique_ptr<Value>(new NullValue()); + } else { + return std::unique_ptr<Value>(new ArrayValue(handler.getValues())); + } + } + } catch (vespalib::IllegalArgumentException& e) { + LOG(warning, "Caught exception while fetching field from document: %s", e.what()); + return std::unique_ptr<Value>(new InvalidValue()); + } catch (FieldNotFoundException& e) { + LOG(warning, "Tried to compare to field %s, not found in document type", _fieldExpression.c_str()); + return std::unique_ptr<Value>(new InvalidValue()); + } +} void FieldValueNode::visit(Visitor &visitor) const diff --git a/document/src/vespa/document/select/valuenode.h b/document/src/vespa/document/select/valuenode.h index d56b1468508..8aae23cb1e4 100644 --- a/document/src/vespa/document/select/valuenode.h +++ b/document/src/vespa/document/select/valuenode.h @@ -228,23 +228,6 @@ public: static vespalib::string extractFieldName(const std::string & fieldExpression); private: - class IteratorHandler : public FieldValue::IteratorHandler - { - public: - IteratorHandler(); - ~IteratorHandler(); - bool hasSingleValue() const; - - std::unique_ptr<Value> getSingleValue(); - const std::vector<ArrayValue::VariableValue>& getValues(); - - private: - std::unique_ptr<Value> _firstValue; - std::vector<ArrayValue::VariableValue> _values; - - void onPrimitive(uint32_t fid, const Content & fv) override; - std::unique_ptr<Value> getInternalValue(const FieldValue& fval) const; - }; void initFieldPath(const DocumentType&) const; }; diff --git a/document/src/vespa/document/update/addfieldpathupdate.cpp b/document/src/vespa/document/update/addfieldpathupdate.cpp index 03a31d882f3..656ee4580a0 100644 --- a/document/src/vespa/document/update/addfieldpathupdate.cpp +++ b/document/src/vespa/document/update/addfieldpathupdate.cpp @@ -1,8 +1,8 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "addfieldpathupdate.h" -#include <vespa/document/fieldvalue/fieldvalues.h> -#include <vespa/document/select/parser.h> +#include <vespa/document/fieldvalue/iteratorhandler.h> +#include <vespa/document/fieldvalue/arrayfieldvalue.h> #include <vespa/document/serialization/vespadocumentdeserializer.h> #include <vespa/vespalib/objects/nbostream.h> #include <vespa/vespalib/util/exceptions.h> @@ -14,14 +14,13 @@ LOG_SETUP(".document.update.fieldpathupdate"); namespace document { +using namespace fieldvalue; +using vespalib::make_string; + IMPLEMENT_IDENTIFIABLE(AddFieldPathUpdate, FieldPathUpdate); -AddFieldPathUpdate::AddFieldPathUpdate( - const DocumentTypeRepo& repo, - const DataType& type, - stringref fieldPath, - stringref whereClause, - const ArrayFieldValue& values) +AddFieldPathUpdate::AddFieldPathUpdate(const DocumentTypeRepo& repo, const DataType& type, + stringref fieldPath, stringref whereClause, const ArrayFieldValue& values) : FieldPathUpdate(repo, type, fieldPath, whereClause), _values(vespalib::CloneablePtr<ArrayFieldValue>(values.clone())) { @@ -39,22 +38,34 @@ AddFieldPathUpdate::clone() const { return new AddFieldPathUpdate(*this); } -FieldValue::IteratorHandler::ModificationStatus -AddFieldPathUpdate::AddIteratorHandler::doModify(FieldValue& fv) -{ +namespace { + +class AddIteratorHandler : public fieldvalue::IteratorHandler { +public: + AddIteratorHandler(const ArrayFieldValue &values) : _values(values) {} + fieldvalue::ModificationStatus doModify(FieldValue &fv) override; + bool createMissingPath() const override { return true; } + bool onComplex(const fieldvalue::IteratorHandler::Content &) override { return false; } +private: + const ArrayFieldValue &_values; +}; + + +ModificationStatus +AddIteratorHandler::doModify(FieldValue &fv) { LOG(spam, "Adding values to %s", fv.toString().c_str()); if (fv.inherits(CollectionFieldValue::classId)) { - CollectionFieldValue& cf = static_cast<CollectionFieldValue&>(fv); + CollectionFieldValue &cf = static_cast<CollectionFieldValue &>(fv); for (std::size_t i = 0; i < _values.size(); ++i) { cf.add(_values[i]); } } else { - vespalib::string err = vespalib::make_string( - "Unable to add a value to a \"%s\" field value.", - fv.getClass().name()); - throw vespalib::IllegalArgumentException(err, VESPA_STRLOC); + vespalib::string err = make_string("Unable to add a value to a \"%s\" field value.", fv.getClass().name()); + throw vespalib::IllegalArgumentException(err, VESPA_STRLOC); } - return MODIFIED; + return ModificationStatus::MODIFIED; +} + } bool @@ -68,8 +79,7 @@ AddFieldPathUpdate::operator==(const FieldPathUpdate& other) const } void -AddFieldPathUpdate::print(std::ostream& out, bool verbose, - const std::string& indent) const +AddFieldPathUpdate::print(std::ostream& out, bool verbose, const std::string& indent) const { out << "AddFieldPathUpdate(\n"; FieldPathUpdate::print(out, verbose, indent + " "); @@ -79,8 +89,7 @@ AddFieldPathUpdate::print(std::ostream& out, bool verbose, } void -AddFieldPathUpdate::deserialize(const DocumentTypeRepo& repo, - const DataType& type, +AddFieldPathUpdate::deserialize(const DocumentTypeRepo& repo, const DataType& type, ByteBuffer& buffer, uint16_t version) { FieldPathUpdate::deserialize(repo, type, buffer, version); @@ -95,4 +104,11 @@ AddFieldPathUpdate::deserialize(const DocumentTypeRepo& repo, buffer.incPos(buffer.getRemaining() - stream.size()); } +std::unique_ptr<IteratorHandler> +AddFieldPathUpdate::getIteratorHandler(Document&) const { + return std::make_unique<AddIteratorHandler>(*_values); +} + + + } // ns document diff --git a/document/src/vespa/document/update/addfieldpathupdate.h b/document/src/vespa/document/update/addfieldpathupdate.h index 6d75ebc4209..94156156257 100644 --- a/document/src/vespa/document/update/addfieldpathupdate.h +++ b/document/src/vespa/document/update/addfieldpathupdate.h @@ -10,7 +10,6 @@ class AddFieldPathUpdate : public FieldPathUpdate public: /** For deserialization */ AddFieldPathUpdate(); - AddFieldPathUpdate(const DocumentTypeRepo& repo, const DataType& type, stringref fieldPath, stringref whereClause, const ArrayFieldValue& values); ~AddFieldPathUpdate(); @@ -18,7 +17,6 @@ public: FieldPathUpdate* clone() const override; bool operator==(const FieldPathUpdate& other) const override; void print(std::ostream& out, bool verbose, const std::string& indent) const override; - const ArrayFieldValue & getValues() const { return *_values; } DECLARE_IDENTIFIABLE(AddFieldPathUpdate); @@ -29,22 +27,7 @@ private: void deserialize(const DocumentTypeRepo& repo, const DataType& type, ByteBuffer& buffer, uint16_t version) override; - class AddIteratorHandler : public FieldValue::IteratorHandler - { - public: - AddIteratorHandler(const ArrayFieldValue& values) : _values(values) { } - - ModificationStatus doModify(FieldValue& fv) override; - bool createMissingPath() const override { return true; } - bool onComplex(const Content&) override { return false; } - private: - const ArrayFieldValue& _values; - }; - - std::unique_ptr<FieldValue::IteratorHandler> getIteratorHandler(Document&) const override { - return std::unique_ptr<FieldValue::IteratorHandler>( - new AddIteratorHandler(*_values)); - } + std::unique_ptr<fieldvalue::IteratorHandler> getIteratorHandler(Document&) const override; vespalib::CloneablePtr<ArrayFieldValue> _values; }; diff --git a/document/src/vespa/document/update/addvalueupdate.cpp b/document/src/vespa/document/update/addvalueupdate.cpp index 910e3d7dd50..b1142836fc2 100644 --- a/document/src/vespa/document/update/addvalueupdate.cpp +++ b/document/src/vespa/document/update/addvalueupdate.cpp @@ -2,17 +2,17 @@ #include "addvalueupdate.h" #include <vespa/document/base/field.h> #include <vespa/document/datatype/arraydatatype.h> -#include <vespa/document/datatype/weightedsetdatatype.h> #include <vespa/document/fieldvalue/fieldvalues.h> -#include <vespa/document/repo/fixedtyperepo.h> #include <vespa/document/serialization/vespadocumentdeserializer.h> -#include <vespa/document/util/serializable.h> #include <vespa/document/util/serializableexceptions.h> #include <vespa/vespalib/objects/nbostream.h> +#include <vespa/vespalib/util/xmlstream.h> + using vespalib::IllegalArgumentException; using vespalib::IllegalStateException; using vespalib::nbostream; +using namespace vespalib::xml; namespace document { diff --git a/document/src/vespa/document/update/arithmeticvalueupdate.cpp b/document/src/vespa/document/update/arithmeticvalueupdate.cpp index 29c24e7140f..a8fe541d0fe 100644 --- a/document/src/vespa/document/update/arithmeticvalueupdate.cpp +++ b/document/src/vespa/document/update/arithmeticvalueupdate.cpp @@ -3,9 +3,11 @@ #include <vespa/document/base/field.h> #include <vespa/document/fieldvalue/fieldvalues.h> #include <vespa/vespalib/util/exceptions.h> +#include <vespa/vespalib/util/xmlstream.h> using vespalib::IllegalArgumentException; using vespalib::IllegalStateException; +using namespace vespalib::xml; namespace document { diff --git a/document/src/vespa/document/update/assignfieldpathupdate.cpp b/document/src/vespa/document/update/assignfieldpathupdate.cpp index 4b8ee510576..3d67a589ea5 100644 --- a/document/src/vespa/document/update/assignfieldpathupdate.cpp +++ b/document/src/vespa/document/update/assignfieldpathupdate.cpp @@ -2,6 +2,7 @@ #include "assignfieldpathupdate.h" #include <vespa/document/fieldvalue/fieldvalues.h> +#include <vespa/document/fieldvalue/iteratorhandler.h> #include <vespa/document/select/parser.h> #include <vespa/document/select/variablemap.h> #include <vespa/document/serialization/vespadocumentdeserializer.h> @@ -16,6 +17,8 @@ using vespalib::nbostream; namespace document { +using namespace fieldvalue; + IMPLEMENT_IDENTIFIABLE(AssignFieldPathUpdate, FieldPathUpdate); AssignFieldPathUpdate::AssignFieldPathUpdate() @@ -69,24 +72,56 @@ FieldPathUpdate* AssignFieldPathUpdate::clone() const { return new AssignFieldPathUpdate(*this); } +namespace { -std::unique_ptr<FieldValue::IteratorHandler> -AssignFieldPathUpdate::getIteratorHandler(Document& doc) const +class AssignValueIteratorHandler : public IteratorHandler { - if (!_expression.empty()) { - return std::unique_ptr<FieldValue::IteratorHandler>( - new AssignExpressionIteratorHandler( - *_repo, doc, _expression, _removeIfZero, _createMissingPath)); - } else { - return std::unique_ptr<FieldValue::IteratorHandler>( - new AssignValueIteratorHandler( - *_newValue, _removeIfZero, _createMissingPath)); - } -} - - -FieldValue::IteratorHandler::ModificationStatus -AssignFieldPathUpdate::AssignValueIteratorHandler::doModify(FieldValue& fv) { +public: + AssignValueIteratorHandler(const FieldValue& newValue, + bool removeIfZero, + bool createMissingPath_) + : _newValue(newValue), _removeIfZero(removeIfZero), + _createMissingPath(createMissingPath_) + {} + + ModificationStatus doModify(FieldValue& fv) override; + bool onComplex(const Content&) override { return false; } + bool createMissingPath() const override { return _createMissingPath; } + +private: + const FieldValue& _newValue; + bool _removeIfZero; + bool _createMissingPath; +}; + +class AssignExpressionIteratorHandler : public IteratorHandler +{ +public: + AssignExpressionIteratorHandler( + const DocumentTypeRepo& repo, + Document& doc, + const vespalib::string& expression, + bool removeIfZero, + bool createMissingPath_) + : _calc(repo, expression), + _doc(doc), + _removeIfZero(removeIfZero), + _createMissingPath(createMissingPath_) + {} + + ModificationStatus doModify(FieldValue& fv) override; + bool onComplex(const Content&) override { return false; } + bool createMissingPath() const override { return _createMissingPath; } + +private: + DocumentCalculator _calc; + Document& _doc; + bool _removeIfZero; + bool _createMissingPath; +}; + +ModificationStatus +AssignValueIteratorHandler::doModify(FieldValue& fv) { LOG(spam, "fv = %s", fv.toString().c_str()); if (!(*fv.getDataType() == *_newValue.getDataType())) { std::string err = vespalib::make_string( @@ -105,8 +140,8 @@ AssignFieldPathUpdate::AssignValueIteratorHandler::doModify(FieldValue& fv) { return MODIFIED; } -FieldValue::IteratorHandler::ModificationStatus -AssignFieldPathUpdate::AssignExpressionIteratorHandler::doModify(FieldValue& fv) { +ModificationStatus +AssignExpressionIteratorHandler::doModify(FieldValue& fv) { LOG(spam, "fv = %s", fv.toString().c_str()); if (fv.inherits(NumericFieldValueBase::classId)) { std::unique_ptr<select::VariableMap> varHolder = std::make_unique<select::VariableMap>(); @@ -146,6 +181,18 @@ AssignFieldPathUpdate::AssignExpressionIteratorHandler::doModify(FieldValue& fv) return MODIFIED; } +} + +std::unique_ptr<IteratorHandler> +AssignFieldPathUpdate::getIteratorHandler(Document& doc) const +{ + if (!_expression.empty()) { + return std::make_unique<AssignExpressionIteratorHandler>(*_repo, doc, _expression, _removeIfZero, _createMissingPath); + } else { + return std::make_unique<AssignValueIteratorHandler>(*_newValue, _removeIfZero, _createMissingPath); + } +} + bool AssignFieldPathUpdate::operator==(const FieldPathUpdate& other) const { diff --git a/document/src/vespa/document/update/assignfieldpathupdate.h b/document/src/vespa/document/update/assignfieldpathupdate.h index 81853246e54..3794cb331ce 100644 --- a/document/src/vespa/document/update/assignfieldpathupdate.h +++ b/document/src/vespa/document/update/assignfieldpathupdate.h @@ -58,53 +58,7 @@ private: void deserialize(const DocumentTypeRepo& repo, const DataType& type, ByteBuffer& buffer, uint16_t version) override; - class AssignValueIteratorHandler : public FieldValue::IteratorHandler - { - public: - AssignValueIteratorHandler(const FieldValue& newValue, - bool removeIfZero, - bool createMissingPath_) - : _newValue(newValue), _removeIfZero(removeIfZero), - _createMissingPath(createMissingPath_) - {} - - ModificationStatus doModify(FieldValue& fv) override; - bool onComplex(const Content&) override { return false; } - bool createMissingPath() const override { return _createMissingPath; } - - private: - const FieldValue& _newValue; - bool _removeIfZero; - bool _createMissingPath; - }; - - class AssignExpressionIteratorHandler : public FieldValue::IteratorHandler - { - public: - AssignExpressionIteratorHandler( - const DocumentTypeRepo& repo, - Document& doc, - const vespalib::string& expression, - bool removeIfZero, - bool createMissingPath_) - : _calc(repo, expression), - _doc(doc), - _removeIfZero(removeIfZero), - _createMissingPath(createMissingPath_) - {} - - ModificationStatus doModify(FieldValue& fv) override; - bool onComplex(const Content&) override { return false; } - bool createMissingPath() const override { return _createMissingPath; } - - private: - DocumentCalculator _calc; - Document& _doc; - bool _removeIfZero; - bool _createMissingPath; - }; - - std::unique_ptr<FieldValue::IteratorHandler> getIteratorHandler(Document& doc) const override; + std::unique_ptr<fieldvalue::IteratorHandler> getIteratorHandler(Document& doc) const override; const DocumentTypeRepo *_repo; FieldValue::CP _newValue; diff --git a/document/src/vespa/document/update/assignvalueupdate.cpp b/document/src/vespa/document/update/assignvalueupdate.cpp index 0538bec10e5..63609ed18c1 100644 --- a/document/src/vespa/document/update/assignvalueupdate.cpp +++ b/document/src/vespa/document/update/assignvalueupdate.cpp @@ -3,14 +3,16 @@ #include "assignvalueupdate.h" #include <vespa/document/base/field.h> #include <vespa/document/fieldvalue/fieldvalues.h> -#include <vespa/document/repo/fixedtyperepo.h> #include <vespa/document/serialization/vespadocumentdeserializer.h> #include <vespa/vespalib/objects/nbostream.h> #include <vespa/vespalib/util/exceptions.h> +#include <vespa/vespalib/util/xmlstream.h> + using vespalib::IllegalArgumentException; using vespalib::IllegalStateException; using vespalib::nbostream; +using namespace vespalib::xml; namespace document { diff --git a/document/src/vespa/document/update/clearvalueupdate.cpp b/document/src/vespa/document/update/clearvalueupdate.cpp index cb526852299..f34987ccfeb 100644 --- a/document/src/vespa/document/update/clearvalueupdate.cpp +++ b/document/src/vespa/document/update/clearvalueupdate.cpp @@ -4,10 +4,12 @@ #include <vespa/document/base/field.h> #include <vespa/document/fieldvalue/document.h> #include <vespa/vespalib/util/exceptions.h> +#include <vespa/vespalib/util/xmlstream.h> #include <ostream> using vespalib::IllegalArgumentException; using vespalib::IllegalStateException; +using namespace vespalib::xml; namespace document { diff --git a/document/src/vespa/document/update/documentupdate.cpp b/document/src/vespa/document/update/documentupdate.cpp index d91b33650d4..43fe6c28dc8 100644 --- a/document/src/vespa/document/update/documentupdate.cpp +++ b/document/src/vespa/document/update/documentupdate.cpp @@ -9,12 +9,14 @@ #include <vespa/document/util/bufferexceptions.h> #include <vespa/document/base/exceptions.h> #include <vespa/document/datatype/documenttype.h> +#include <vespa/vespalib/util/xmlstream.h> using vespalib::IllegalArgumentException; using vespalib::IllegalStateException; using vespalib::nbostream; using vespalib::make_string; using vespalib::string; +using namespace vespalib::xml; namespace document { diff --git a/document/src/vespa/document/update/fieldpathupdate.cpp b/document/src/vespa/document/update/fieldpathupdate.cpp index a4145a9b58a..37672ac0b1d 100644 --- a/document/src/vespa/document/update/fieldpathupdate.cpp +++ b/document/src/vespa/document/update/fieldpathupdate.cpp @@ -1,14 +1,20 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/document/fieldvalue/fieldvalues.h> +#include "fieldpathupdates.h" +#include <vespa/document/fieldvalue/document.h> +#include <vespa/document/fieldvalue/iteratorhandler.h> #include <vespa/document/select/parser.h> -#include <vespa/document/update/fieldpathupdates.h> #include <vespa/document/util/serializableexceptions.h> #include <vespa/log/log.h> LOG_SETUP(".document.update.fieldpathupdate"); +using vespalib::make_string; +using vespalib::IllegalArgumentException; + namespace document { +using namespace fieldvalue; + IMPLEMENT_IDENTIFIABLE_ABSTRACT(FieldPathUpdate, Identifiable); namespace { @@ -43,9 +49,9 @@ FieldPathUpdate::FieldPathUpdate(const DocumentTypeRepo& repo, : std::unique_ptr<select::Node>()) { if (!_fieldPath.get()) { - throw vespalib::IllegalArgumentException( - vespalib::make_string("Could not create field path update for: path='%s', where='%s'", - fieldPath.c_str(), whereClause.c_str()), VESPA_STRLOC); + throw IllegalArgumentException( + make_string("Could not create field path update for: path='%s', where='%s'", + fieldPath.c_str(), whereClause.c_str()), VESPA_STRLOC); } } @@ -61,7 +67,7 @@ FieldPathUpdate::operator==(const FieldPathUpdate& other) const void FieldPathUpdate::applyTo(Document& doc) const { - std::unique_ptr<FieldValue::IteratorHandler> handler(getIteratorHandler(doc)); + std::unique_ptr<IteratorHandler> handler(getIteratorHandler(doc)); if (!_whereClause) { doc.iterateNested(*_fieldPath, *handler); @@ -70,7 +76,7 @@ FieldPathUpdate::applyTo(Document& doc) const for (select::ResultList::const_iterator i = results.begin(); i != results.end(); ++i) { - LOG(spam, "vars = %s", FieldValue::IteratorHandler::toString(handler->getVariables()).c_str()); + LOG(spam, "vars = %s", handler->getVariables().toString().c_str()); if (*i->second == select::Result::True) { handler->setVariables(i->first); doc.iterateNested(*_fieldPath, *handler); @@ -88,8 +94,7 @@ FieldPathUpdate::affectsDocumentBody() const } void -FieldPathUpdate::print(std::ostream& out, bool, - const std::string& indent) const +FieldPathUpdate::print(std::ostream& out, bool, const std::string& indent) const { out << indent << "fieldPath='" << _originalFieldPath << "',\n" << indent << "whereClause='" << _originalWhereClause << "'"; @@ -99,10 +104,10 @@ void FieldPathUpdate::checkCompatibility(const FieldValue& fv) const { if ( !getResultingDataType().isValueType(fv)) { - throw vespalib::IllegalArgumentException( - vespalib::make_string("Cannot update a '%s' field with a '%s' value", - getResultingDataType().toString().c_str(), - fv.getDataType()->toString().c_str()), + throw IllegalArgumentException( + make_string("Cannot update a '%s' field with a '%s' value", + getResultingDataType().toString().c_str(), + fv.getDataType()->toString().c_str()), VESPA_STRLOC); } } @@ -111,8 +116,7 @@ const DataType& FieldPathUpdate::getResultingDataType() const { if (_fieldPath->empty()) { - throw vespalib::IllegalStateException("Cannot get resulting data " - "type from an empty field path", VESPA_STRLOC); + throw vespalib::IllegalStateException("Cannot get resulting data type from an empty field path", VESPA_STRLOC); } return _fieldPath->rbegin()->getDataType(); } @@ -138,9 +142,7 @@ FieldPathUpdate::deserialize(const DocumentTypeRepo& repo, try { _fieldPath = type.buildFieldPath(_originalFieldPath).release(); if (!_fieldPath.get()) { - throw DeserializeException( - vespalib::make_string("Invalid field path: '%s'", _originalFieldPath.c_str()), - VESPA_STRLOC); + throw DeserializeException(make_string("Invalid field path: '%s'", _originalFieldPath.c_str()), VESPA_STRLOC); } _whereClause = !_originalWhereClause.empty() ? parseDocumentSelection(_originalWhereClause, repo) @@ -159,8 +161,7 @@ FieldPathUpdate::createInstance(const DocumentTypeRepo& repo, buffer.getByte(updateType); std::unique_ptr<FieldPathUpdate> update; - switch (updateType) - { + switch (updateType) { case 0: update.reset(new AssignFieldPathUpdate()); break; @@ -171,9 +172,7 @@ FieldPathUpdate::createInstance(const DocumentTypeRepo& repo, update.reset(new AddFieldPathUpdate()); break; default: - throw DeserializeException( - vespalib::make_string("Unknown fieldpath update type: %d", updateType), - VESPA_STRLOC); + throw DeserializeException(make_string("Unknown fieldpath update type: %d", updateType), VESPA_STRLOC); } update->deserialize(repo, type, buffer, serializationVersion); return update; diff --git a/document/src/vespa/document/update/fieldpathupdate.h b/document/src/vespa/document/update/fieldpathupdate.h index 80a63d62281..0eaff9485bf 100644 --- a/document/src/vespa/document/update/fieldpathupdate.h +++ b/document/src/vespa/document/update/fieldpathupdate.h @@ -104,8 +104,7 @@ protected: enum SerializedMagic {AssignMagic=0, RemoveMagic=1, AddMagic=2}; private: // TODO: rename to createIteratorHandler? - virtual std::unique_ptr<FieldValue::IteratorHandler> getIteratorHandler( - Document& doc) const = 0; + virtual std::unique_ptr<fieldvalue::IteratorHandler> getIteratorHandler(Document& doc) const = 0; vespalib::string _originalFieldPath; vespalib::string _originalWhereClause; diff --git a/document/src/vespa/document/update/mapvalueupdate.cpp b/document/src/vespa/document/update/mapvalueupdate.cpp index 0a92fa7fb15..37d775bb204 100644 --- a/document/src/vespa/document/update/mapvalueupdate.cpp +++ b/document/src/vespa/document/update/mapvalueupdate.cpp @@ -5,13 +5,14 @@ #include <vespa/document/serialization/vespadocumentdeserializer.h> #include <vespa/vespalib/objects/nbostream.h> #include <vespa/document/util/serializableexceptions.h> +#include <vespa/vespalib/util/xmlstream.h> using vespalib::IllegalArgumentException; using vespalib::IllegalStateException; using vespalib::nbostream; +using namespace vespalib::xml; -namespace document -{ +namespace document { IMPLEMENT_IDENTIFIABLE(MapValueUpdate, ValueUpdate); diff --git a/document/src/vespa/document/update/removefieldpathupdate.cpp b/document/src/vespa/document/update/removefieldpathupdate.cpp index 6c9d60abd2f..4af867995d9 100644 --- a/document/src/vespa/document/update/removefieldpathupdate.cpp +++ b/document/src/vespa/document/update/removefieldpathupdate.cpp @@ -1,11 +1,13 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "removefieldpathupdate.h" -#include <vespa/document/fieldvalue/fieldvalues.h> -#include <vespa/document/select/parser.h> +#include <vespa/document/fieldvalue/iteratorhandler.h> +#include <ostream> namespace document { +using namespace fieldvalue; + IMPLEMENT_IDENTIFIABLE(RemoveFieldPathUpdate, FieldPathUpdate); RemoveFieldPathUpdate::RemoveFieldPathUpdate() @@ -30,8 +32,7 @@ RemoveFieldPathUpdate::operator==(const FieldPathUpdate& other) const } void -RemoveFieldPathUpdate::print(std::ostream& out, bool verbose, - const std::string& indent) const +RemoveFieldPathUpdate::print(std::ostream& out, bool verbose, const std::string& indent) const { out << "RemoveFieldPathUpdate(\n"; FieldPathUpdate::print(out, verbose, indent + " "); @@ -39,11 +40,28 @@ RemoveFieldPathUpdate::print(std::ostream& out, bool verbose, } void -RemoveFieldPathUpdate::deserialize( - const DocumentTypeRepo& repo, const DataType& type, - ByteBuffer& buffer, uint16_t version) +RemoveFieldPathUpdate::deserialize(const DocumentTypeRepo& repo, const DataType& type, + ByteBuffer& buffer, uint16_t version) { FieldPathUpdate::deserialize(repo, type, buffer, version); } +namespace { + +class RemoveIteratorHandler : public IteratorHandler { +public: + RemoveIteratorHandler() {} + + ModificationStatus doModify(FieldValue &) override { + return ModificationStatus::REMOVED; + } +}; + +} + +std::unique_ptr<IteratorHandler> +RemoveFieldPathUpdate::getIteratorHandler(Document&) const { + return std::make_unique<RemoveIteratorHandler>(); +} + } // ns document diff --git a/document/src/vespa/document/update/removefieldpathupdate.h b/document/src/vespa/document/update/removefieldpathupdate.h index 6de2a105cbf..1a3865fe761 100644 --- a/document/src/vespa/document/update/removefieldpathupdate.h +++ b/document/src/vespa/document/update/removefieldpathupdate.h @@ -29,19 +29,7 @@ private: void deserialize(const DocumentTypeRepo& repo, const DataType& type, ByteBuffer& buffer, uint16_t version) override; - class RemoveIteratorHandler : public FieldValue::IteratorHandler - { - public: - RemoveIteratorHandler() {} - - ModificationStatus doModify(FieldValue&) override { - return REMOVED; - } - }; - - std::unique_ptr<FieldValue::IteratorHandler> getIteratorHandler(Document&) const override { - return std::make_unique<RemoveIteratorHandler>(); - } + std::unique_ptr<fieldvalue::IteratorHandler> getIteratorHandler(Document&) const override; }; diff --git a/document/src/vespa/document/update/removevalueupdate.cpp b/document/src/vespa/document/update/removevalueupdate.cpp index e0575f600da..34af57edbe8 100644 --- a/document/src/vespa/document/update/removevalueupdate.cpp +++ b/document/src/vespa/document/update/removevalueupdate.cpp @@ -1,20 +1,20 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include "removevalueupdate.h" #include <vespa/document/base/field.h> #include <vespa/document/datatype/arraydatatype.h> #include <vespa/document/datatype/weightedsetdatatype.h> #include <vespa/document/fieldvalue/fieldvalues.h> -#include <vespa/document/repo/fixedtyperepo.h> #include <vespa/document/serialization/vespadocumentdeserializer.h> -#include <vespa/document/update/removevalueupdate.h> #include <vespa/vespalib/objects/nbostream.h> #include <vespa/document/util/serializableexceptions.h> +#include <vespa/vespalib/util/xmlstream.h> using vespalib::IllegalArgumentException; using vespalib::IllegalStateException; using vespalib::nbostream; +using namespace vespalib::xml; -namespace document -{ +namespace document { IMPLEMENT_IDENTIFIABLE(RemoveValueUpdate, ValueUpdate); diff --git a/document/src/vespa/document/util/xmlserializable.h b/document/src/vespa/document/util/xmlserializable.h index 21e0b858dec..f74761a04f6 100644 --- a/document/src/vespa/document/util/xmlserializable.h +++ b/document/src/vespa/document/util/xmlserializable.h @@ -5,14 +5,6 @@ #include <vespa/vespalib/util/xmlserializable.h> namespace document { - typedef vespalib::xml::XmlOutputStream XmlOutputStream; - typedef vespalib::xml::XmlSerializable XmlSerializable; - typedef vespalib::xml::XmlTag XmlTag; - typedef vespalib::xml::XmlEndTag XmlEndTag; - typedef vespalib::xml::XmlAttribute XmlAttribute; - typedef vespalib::xml::XmlContent XmlContent; - typedef vespalib::xml::XmlEscapedContent XmlEscapedContent; - typedef vespalib::xml::XmlBase64Content XmlBase64Content; - typedef vespalib::xml::XmlContentWrapper XmlContentWrapper; + using XmlSerializable = vespalib::xml::XmlSerializable; + using XmlOutputStream = vespalib::xml::XmlOutputStream; } - |