diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2017-04-24 15:26:22 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-24 15:26:22 +0200 |
commit | 5a1b72a923e086e6df31c9eda32791df75f50c97 (patch) | |
tree | e0c55d72fddb26923b043a8fed26274991e3035d /document | |
parent | 6bc31f5ea71437ec198519329a39a23b87322597 (diff) | |
parent | 9e383f5102e1659592b0c8b5ff3d06012e760b85 (diff) |
Merge pull request #2244 from yahoo/balder/optimize-streaming-1
Balder/optimize streaming 1
Diffstat (limited to 'document')
14 files changed, 121 insertions, 153 deletions
diff --git a/document/src/tests/documenttestcase.cpp b/document/src/tests/documenttestcase.cpp index d9b188278fd..b100487a94e 100644 --- a/document/src/tests/documenttestcase.cpp +++ b/document/src/tests/documenttestcase.cpp @@ -179,7 +179,7 @@ void DocumentTest::testTraversing() Handler fullTraverser; FieldPath empty; - doc.iterateNested(empty.begin(), empty.end(), fullTraverser); + doc.iterateNested(empty.getFullRange(), fullTraverser); CPPUNIT_ASSERT_EQUAL(fullTraverser.getResult(), std::string("<P<P<PP[PPP][<PP><PP>]>>>")); } @@ -231,7 +231,7 @@ DocumentTest::testVariables() { VariableIteratorHandler handler; FieldPath::UP path = type.buildFieldPath("iiiarray[$x][$y][$z]"); - doc.iterateNested(path->begin(), path->end(), handler); + doc.iterateNested(path->getFullRange(), handler); std::string fasit = "x: 0,y: 0,z: 0, - 1\n" @@ -388,7 +388,7 @@ DocumentTest::testModifyDocument() FieldPath::UP path = doc->getDataType()->buildFieldPath("l1s1.structmap.value.smap{leonardo}"); - doc->iterateNested(path->begin(), path->end(), handler); + doc->iterateNested(path->getFullRange(), handler); doc->print(std::cerr, true, ""); } diff --git a/document/src/vespa/document/base/fieldpath.h b/document/src/vespa/document/base/fieldpath.h index c795aa48950..d5a0efb5947 100644 --- a/document/src/vespa/document/base/fieldpath.h +++ b/document/src/vespa/document/base/fieldpath.h @@ -162,9 +162,22 @@ public: virtual void visitMembers(vespalib::ObjectVisitor &visitor) const; + template <typename IT> + class Range { + public: + Range() : _begin(), _end() { } + Range(IT begin_, IT end_) : _begin(begin_), _end(end_) { } + Range next() const { return Range(_begin+1, _end); } + bool atEnd() const { return _begin == _end; } + const FieldPathEntry & cur() { return *_begin; } + private: + IT _begin; + IT _end; + }; + + Range<const_iterator> getFullRange() const { return Range<const_iterator>(begin(), end()); } private: Container _path; }; } - diff --git a/document/src/vespa/document/fieldvalue/arrayfieldvalue.cpp b/document/src/vespa/document/fieldvalue/arrayfieldvalue.cpp index d71d841f851..866c82a63c9 100644 --- a/document/src/vespa/document/fieldvalue/arrayfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/arrayfieldvalue.cpp @@ -176,11 +176,9 @@ ArrayFieldValue::hasChanged() const } FieldValue::IteratorHandler::ModificationStatus -ArrayFieldValue::iterateSubset(int startPos, - int endPos, +ArrayFieldValue::iterateSubset(int startPos, int endPos, const vespalib::stringref & variable, - FieldPath::const_iterator nextPos, - FieldPath::const_iterator end_, + PathRange nested, IteratorHandler& handler) const { FieldValue::IteratorHandler::ModificationStatus @@ -197,7 +195,7 @@ ArrayFieldValue::iterateSubset(int startPos, } FieldValue::IteratorHandler::ModificationStatus - status = array()[i].iterateNested(nextPos, end_, handler); + status = array()[i].iterateNested(nested, handler); if (status == FieldValue::IteratorHandler::REMOVED) { indicesToRemove.push_back(i); @@ -221,22 +219,22 @@ ArrayFieldValue::iterateSubset(int startPos, } FieldValue::IteratorHandler::ModificationStatus -ArrayFieldValue::onIterateNested(FieldPath::const_iterator start, FieldPath::const_iterator end_, IteratorHandler & handler) const +ArrayFieldValue::onIterateNested(PathRange nested, IteratorHandler & handler) const { IteratorHandler::CollectionScope autoScope(handler, *this); LOG(spam, "iterating over ArrayFieldValue %s", toString().c_str()); - if (start != end_) { - switch (start->getType()) { - case FieldPathEntry::ARRAY_INDEX: + if (! nested.atEnd()) { + const FieldPathEntry & fpe = nested.cur(); + switch (fpe.getType()) { + case FieldPathEntry::ARRAY_INDEX: { LOG(spam, "ARRAY_INDEX"); - return iterateSubset(start->getIndex(), start->getIndex(), - "", start + 1, end_, handler); + return iterateSubset(fpe.getIndex(), fpe.getIndex(), "", nested.next(), handler); + } case FieldPathEntry::VARIABLE: { LOG(spam, "VARIABLE"); - IteratorHandler::VariableMap::iterator - iter = handler.getVariables().find(start->getVariableName()); + IteratorHandler::VariableMap::iterator iter = handler.getVariables().find(fpe.getVariableName()); if (iter != handler.getVariables().end()) { int idx = iter->second.index; @@ -247,22 +245,20 @@ ArrayFieldValue::onIterateNested(FieldPath::const_iterator start, FieldPath::con } if (idx < (int)_array->size()) { - return iterateSubset(idx, idx, "", start + 1, end_, handler); + return iterateSubset(idx, idx, "", nested.next(), handler); } } else { return iterateSubset(0, static_cast<int>(_array->size()) - 1, - start->getVariableName(), start + 1, end_, handler); + fpe.getVariableName(), nested.next(), handler); } break; } default: break; } - return iterateSubset(0, static_cast<int>(_array->size()) - 1, "", - start, end_, handler); + return iterateSubset(0, static_cast<int>(_array->size()) - 1, "", nested, handler); } else { - IteratorHandler::ModificationStatus - status = handler.modify(const_cast<ArrayFieldValue&>(*this)); + IteratorHandler::ModificationStatus status = handler.modify(const_cast<ArrayFieldValue&>(*this)); if (status == FieldValue::IteratorHandler::REMOVED) { return status; @@ -270,7 +266,7 @@ ArrayFieldValue::onIterateNested(FieldPath::const_iterator start, FieldPath::con if (handler.handleComplex(*this)) { if (iterateSubset(0, static_cast<int>(_array->size()) - 1, "", - start, end_, handler) != FieldValue::IteratorHandler::NOT_MODIFIED) + nested, handler) != FieldValue::IteratorHandler::NOT_MODIFIED) { status = FieldValue::IteratorHandler::MODIFIED; } diff --git a/document/src/vespa/document/fieldvalue/arrayfieldvalue.h b/document/src/vespa/document/fieldvalue/arrayfieldvalue.h index 0ee300e75db..33e07e18588 100644 --- a/document/src/vespa/document/fieldvalue/arrayfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/arrayfieldvalue.h @@ -26,12 +26,9 @@ private: bool removeValue(const FieldValue& val) override; IteratorHandler::ModificationStatus iterateSubset( int startPos, int endPos, const vespalib::stringref & variable, - FieldPath::const_iterator nextPos, - FieldPath::const_iterator end_, + PathRange nested, IteratorHandler& handler) const; - IteratorHandler::ModificationStatus onIterateNested( - FieldPath::const_iterator start, FieldPath::const_iterator end, - IteratorHandler & handler) const override; + IteratorHandler::ModificationStatus onIterateNested(PathRange nested, IteratorHandler & handler) const override; public: typedef IArray::const_iterator const_iterator; typedef IArray::iterator iterator; diff --git a/document/src/vespa/document/fieldvalue/document.h b/document/src/vespa/document/fieldvalue/document.h index d55730e0046..f159e9be1d5 100644 --- a/document/src/vespa/document/fieldvalue/document.h +++ b/document/src/vespa/document/fieldvalue/document.h @@ -167,5 +167,5 @@ private: const DocumentTypeRepo& repo, ByteBuffer& buffer, DocumentId& id, const DocumentType * docType); }; -} // document +} // document diff --git a/document/src/vespa/document/fieldvalue/fieldvalue.cpp b/document/src/vespa/document/fieldvalue/fieldvalue.cpp index 555a50cdb47..fd3093488ea 100644 --- a/document/src/vespa/document/fieldvalue/fieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/fieldvalue.cpp @@ -12,14 +12,8 @@ #include "predicatefieldvalue.h" #include <vespa/document/base/exceptions.h> -#include <vespa/document/datatype/arraydatatype.h> -#include <vespa/document/datatype/numericdatatype.h> -#include <vespa/document/datatype/primitivedatatype.h> #include <vespa/document/serialization/vespadocumentserializer.h> -#include <vespa/document/util/bytebuffer.h> -#include <vespa/vespalib/objects/fieldbase.h> #include <vespa/vespalib/objects/nbostream.h> -#include <vespa/document/util/serializableexceptions.h> #include <sstream> using vespalib::FieldBase; @@ -161,29 +155,30 @@ std::pair<const char*, size_t> FieldValue::getAsRaw() const *getDataType(), *DataType::RAW, VESPA_STRLOC); } -FieldValue::UP FieldValue::getNestedFieldValue(FieldPath::const_iterator start, FieldPath::const_iterator end) const +FieldValue::UP +FieldValue::getNestedFieldValue(PathRange nested) const { - return (start != end) ? onGetNestedFieldValue(start, end) : FieldValue::UP(); + return ( ! nested.atEnd() ) ? onGetNestedFieldValue(nested) : FieldValue::UP(); } -FieldValue::UP FieldValue::onGetNestedFieldValue(FieldPath::const_iterator start, FieldPath::const_iterator end) const +FieldValue::UP +FieldValue::onGetNestedFieldValue(PathRange nested) const { - (void) start; - (void) end; + (void) nested; return FieldValue::UP(); } FieldValue::IteratorHandler::ModificationStatus -FieldValue::iterateNested(FieldPath::const_iterator start, FieldPath::const_iterator end, IteratorHandler & handler) const +FieldValue::iterateNested(PathRange nested, IteratorHandler & handler) const { - return onIterateNested(start, end, handler); + return onIterateNested(nested, handler); } FieldValue::IteratorHandler::ModificationStatus -FieldValue::onIterateNested(FieldPath::const_iterator start, FieldPath::const_iterator end, IteratorHandler & handler) const +FieldValue::onIterateNested(PathRange nested, IteratorHandler & handler) const { - if (start == end) { - handler.handlePrimitive(*this); + if (nested.atEnd()) { + handler.handlePrimitive(-1, *this); return handler.modify(const_cast<FieldValue&>(*this)); } else { throw vespalib::IllegalArgumentException("Primitive types can't be iterated through"); @@ -221,8 +216,8 @@ FieldValue::IteratorHandler::IndexValue::toString() const { } void -FieldValue::IteratorHandler::handlePrimitive(const FieldValue & fv) { - onPrimitive(-1, Content(fv, getWeight())); +FieldValue::IteratorHandler::handlePrimitive(uint32_t fid, const FieldValue & fv) { + onPrimitive(fid, Content(fv, getWeight())); } bool FieldValue::IteratorHandler::handleComplex(const FieldValue & fv) { diff --git a/document/src/vespa/document/fieldvalue/fieldvalue.h b/document/src/vespa/document/fieldvalue/fieldvalue.h index 7d8b7ded976..bb2a10a3f53 100644 --- a/document/src/vespa/document/fieldvalue/fieldvalue.h +++ b/document/src/vespa/document/fieldvalue/fieldvalue.h @@ -11,7 +11,6 @@ */ #pragma once - #include "fieldvaluevisitor.h" #include <vespa/document/datatype/datatype.h> #include <vespa/document/util/xmlserializable.h> @@ -35,9 +34,10 @@ protected: static IArray::UP createArray(const DataType & baseType); public: - typedef std::unique_ptr<FieldValue> UP; - typedef std::shared_ptr<FieldValue> SP; - typedef vespalib::CloneablePtr<FieldValue> CP; + using PathRange = FieldPath::Range<FieldPath::const_iterator>; + using UP = std::unique_ptr<FieldValue>; + using SP = std::shared_ptr<FieldValue>; + using CP = vespalib::CloneablePtr<FieldValue>; class IteratorHandler { public: @@ -109,7 +109,7 @@ public: public: virtual ~IteratorHandler(); - void handlePrimitive(const FieldValue & fv); + void handlePrimitive(uint32_t fid, const FieldValue & fv); /** Handles a complex type (struct/array/map etc) that is at the end of the @@ -267,9 +267,7 @@ public: * Will give you the leaf fieldvalue you are looking for in your fieldPath. * If the path does not lead anywhere an empty UP will be returned. */ - FieldValue::UP getNestedFieldValue( - FieldPath::const_iterator start, - FieldPath::const_iterator end) const; + FieldValue::UP getNestedFieldValue(PathRange nested) const; /** * Will iterate the possibly nested fieldvalue depth first. @@ -278,21 +276,13 @@ public: * invocations of the before mentioned methods and the additional * onPrimitive. */ - IteratorHandler::ModificationStatus iterateNested( - FieldPath::const_iterator start, - FieldPath::const_iterator end, - IteratorHandler & handler) const; - - IteratorHandler::ModificationStatus iterateNested( - const FieldPath& fieldPath, - IteratorHandler& handler) const - { + IteratorHandler::ModificationStatus iterateNested(PathRange nested, IteratorHandler & handler) const; + + IteratorHandler::ModificationStatus iterateNested(const FieldPath& fieldPath, IteratorHandler& handler) const { return iterateNested(fieldPath.begin(), fieldPath.end(), handler); } - virtual void print(std::ostream& out, - bool verbose, - const std::string& indent) const = 0; + virtual void print(std::ostream& out, bool verbose, const std::string& indent) const = 0; // Duplication to reduce size of FieldValue void print(std::ostream& out) const { print(out, false, ""); } void print(std::ostream& out, bool verbose) const { print(out, verbose, ""); } @@ -302,14 +292,12 @@ public: virtual void printXml(XmlOutputStream& out) const = 0; private: - virtual FieldValue::UP onGetNestedFieldValue( - FieldPath::const_iterator start, - FieldPath::const_iterator end) const; - - virtual IteratorHandler::ModificationStatus onIterateNested( - FieldPath::const_iterator start, - FieldPath::const_iterator end, - IteratorHandler & handler) const; + IteratorHandler::ModificationStatus + iterateNested(FieldPath::const_iterator start, FieldPath::const_iterator end, 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; }; std::ostream& operator<<(std::ostream& out, const FieldValue & p); @@ -317,4 +305,3 @@ std::ostream& operator<<(std::ostream& out, const FieldValue & p); XmlOutputStream & operator<<(XmlOutputStream & out, const FieldValue & p); } // document - diff --git a/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp b/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp index 368a903d3cf..2186ff28f60 100644 --- a/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp @@ -284,8 +284,7 @@ MapFieldValue::checkAndRemove(const FieldValue& key, } FieldValue::IteratorHandler::ModificationStatus -MapFieldValue::iterateNestedImpl(FieldPath::const_iterator start, - FieldPath::const_iterator end_, +MapFieldValue::iterateNestedImpl(PathRange nested, IteratorHandler & handler, const FieldValue& complexFieldValue) const { @@ -294,25 +293,25 @@ MapFieldValue::iterateNestedImpl(FieldPath::const_iterator start, bool wasModified = false; const bool isWSet(complexFieldValue.inherits(WeightedSetFieldValue::classId)); - if (start != end_) { + if ( ! nested.atEnd() ) { LOG(spam, "not yet at end of field path"); - switch (start->getType()) { + const FieldPathEntry & fpe = nested.cur(); + switch (fpe.getType()) { case FieldPathEntry::MAP_KEY: { LOG(spam, "MAP_KEY"); - const_iterator iter = find(*start->getLookupKey()); + const_iterator iter = find(*fpe.getLookupKey()); if (iter != end()) { - wasModified = checkAndRemove(*start->getLookupKey(), - iter->second->iterateNested(start + 1, end_, handler), + wasModified = checkAndRemove(*fpe.getLookupKey(), + iter->second->iterateNested(nested.next(), handler), wasModified, keysToRemove); } else if (handler.createMissingPath()) { LOG(spam, "creating missing path"); FieldValue::UP val = getMapType().getValueType().createFieldValue(); - IteratorHandler::ModificationStatus status - = val->iterateNested(start + 1, end_, handler); + IteratorHandler::ModificationStatus status = val->iterateNested(nested.next(), handler); if (status == IteratorHandler::MODIFIED) { - const_cast<MapFieldValue&>(*this).put(FieldValue::UP(start->getLookupKey()->clone()), std::move(val)); + const_cast<MapFieldValue&>(*this).put(FieldValue::UP(fpe.getLookupKey()->clone()), std::move(val)); return status; } } @@ -325,43 +324,44 @@ MapFieldValue::iterateNestedImpl(FieldPath::const_iterator start, handler.setWeight(static_cast<const IntFieldValue &>(*it->second).getValue()); } wasModified = checkAndRemove(*it->first, - it->first->iterateNested(start + 1, end_, handler), - wasModified, keysToRemove); + it->first->iterateNested(nested.next(), handler), + wasModified, keysToRemove); } break; case FieldPathEntry::MAP_ALL_VALUES: LOG(spam, "MAP_ALL_VALUES"); for (const_iterator it(begin()), mt(end()); it != mt; it++) { wasModified = checkAndRemove(*it->second, - it->second->iterateNested(start + 1, end_, handler), - wasModified, keysToRemove); + it->second->iterateNested(nested.next(), handler), + wasModified, keysToRemove); } break; case FieldPathEntry::VARIABLE: { LOG(spam, "VARIABLE"); IteratorHandler::VariableMap::iterator - iter = handler.getVariables().find(start->getVariableName()); + 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); if (found != end()) { wasModified = checkAndRemove(*iter->second.key, - found->second->iterateNested(start + 1, end_, handler), - wasModified, keysToRemove); + found->second->iterateNested(nested.next(), handler), + wasModified, keysToRemove); } } else { + 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()[start->getVariableName()] + 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(start + 1, end_, handler), - wasModified, keysToRemove); + it->second->iterateNested(next, handler), + wasModified, keysToRemove); } - handler.getVariables().erase(start->getVariableName()); + handler.getVariables().erase(fpe.getVariableName()); } break; } @@ -372,8 +372,8 @@ MapFieldValue::iterateNestedImpl(FieldPath::const_iterator start, handler.setWeight(static_cast<const IntFieldValue &>(*it->second).getValue()); } wasModified = checkAndRemove(*it->first, - it->first->iterateNested(start, end_, handler), - wasModified, keysToRemove); + it->first->iterateNested(nested, handler), + wasModified, keysToRemove); // Don't iterate over values /*wasModified = checkAndRemove(*it->second, it->second->iterateNested(start, end_, handler), @@ -401,7 +401,7 @@ MapFieldValue::iterateNestedImpl(FieldPath::const_iterator start, handler.setWeight(static_cast<const IntFieldValue &>(*it->second).getValue()); } wasModified = checkAndRemove(*it->first, - it->first->iterateNested(start, end_, handler), + it->first->iterateNested(nested, handler), wasModified, keysToRemove); // XXX: Map value iteration is currently disabled since it changes // existing search behavior @@ -423,12 +423,10 @@ MapFieldValue::iterateNestedImpl(FieldPath::const_iterator start, } FieldValue::IteratorHandler::ModificationStatus -MapFieldValue::onIterateNested(FieldPath::const_iterator start, - FieldPath::const_iterator end_, - IteratorHandler & handler) const +MapFieldValue::onIterateNested(PathRange nested, IteratorHandler & handler) const { LOG(spam, "iterating over MapFieldValue"); - return iterateNestedImpl(start, end_, handler, *this); + return iterateNestedImpl(nested, handler, *this); } diff --git a/document/src/vespa/document/fieldvalue/mapfieldvalue.h b/document/src/vespa/document/fieldvalue/mapfieldvalue.h index 4538ea0ff81..8b480cbb7f9 100644 --- a/document/src/vespa/document/fieldvalue/mapfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/mapfieldvalue.h @@ -7,7 +7,7 @@ */ #pragma once -#include <vespa/document/fieldvalue/fieldvalue.h> +#include "fieldvalue.h" #include <vespa/document/datatype/mapdatatype.h> #include <vespa/vespalib/util/polymorphicarrays.h> @@ -29,9 +29,7 @@ private: FieldValue::IteratorHandler::ModificationStatus status, bool wasModified, std::vector<const FieldValue*>& keysToRemove) const; - IteratorHandler::ModificationStatus onIterateNested( - FieldPath::const_iterator start, FieldPath::const_iterator end, - IteratorHandler & handler) const override; + IteratorHandler::ModificationStatus onIterateNested(PathRange nested, IteratorHandler & handler) const override; // Utility method to avoid constant explicit casting const MapDataType& getMapType() const { return *_type; } @@ -120,11 +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( - FieldPath::const_iterator start, - FieldPath::const_iterator end_, - IteratorHandler & handler, - const FieldValue& complexFieldValue) const; + IteratorHandler::ModificationStatus iterateNestedImpl(PathRange nested, IteratorHandler & handler, + const FieldValue& complexFieldValue) const; // FieldValue implementation FieldValue& assign(const FieldValue&) override; diff --git a/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp b/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp index d343f9d5845..6d77d101ff2 100644 --- a/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp @@ -17,8 +17,7 @@ StructuredFieldValue::Iterator::Iterator() { } -StructuredFieldValue::Iterator::Iterator(const StructuredFieldValue& owner, - const Field* first) +StructuredFieldValue::Iterator::Iterator(const StructuredFieldValue& owner, const Field* first) : _owner(&const_cast<StructuredFieldValue&>(owner)), _iterator(owner.getIterator(first).release()), _field(_iterator->getNextField()) @@ -70,43 +69,38 @@ void StructuredFieldValue::setFieldValue(const Field & field, const FieldValue & } FieldValue::UP -StructuredFieldValue::onGetNestedFieldValue( - FieldPath::const_iterator start, - FieldPath::const_iterator end_) const +StructuredFieldValue::onGetNestedFieldValue(PathRange nested) const { - FieldValue::UP fv = getValue(start->getFieldRef()); + FieldValue::UP fv = getValue(nested.cur().getFieldRef()); if (fv.get() != NULL) { - if ((start + 1) != end_) { - return fv->getNestedFieldValue(start + 1, end_); + PathRange next = nested.next(); + if ( ! next.atEnd() ) { + return fv->getNestedFieldValue(next); } } return fv; } FieldValue::IteratorHandler::ModificationStatus -StructuredFieldValue::onIterateNested( - FieldPath::const_iterator start, - FieldPath::const_iterator end_, - IteratorHandler & handler) const +StructuredFieldValue::onIterateNested(PathRange nested, IteratorHandler & handler) const { IteratorHandler::StructScope autoScope(handler, *this); - if (start != end_) { - if (start->getType() == FieldPathEntry::STRUCT_FIELD) { - bool exists = getValue(start->getFieldRef(), start->getFieldValueToSet()); - LOG(spam, "fieldRef = %s", start->getFieldRef().toString().c_str()); - LOG(spam, "fieldValueToSet = %s", start->getFieldValueToSet().toString().c_str()); + if ( ! nested.atEnd()) { + const FieldPathEntry & fpe = nested.cur(); + if (fpe.getType() == FieldPathEntry::STRUCT_FIELD) { + bool exists = getValue(fpe.getFieldRef(), fpe.getFieldValueToSet()); + LOG(spam, "fieldRef = %s", fpe.getFieldRef().toString().c_str()); + LOG(spam, "fieldValueToSet = %s", fpe.getFieldValueToSet().toString().c_str()); if (exists) { - IteratorHandler::ModificationStatus - status = start->getFieldValueToSet().iterateNested(start + 1, end_, handler); + IteratorHandler::ModificationStatus status = fpe.getFieldValueToSet().iterateNested(nested.next(), handler); if (status == IteratorHandler::REMOVED) { LOG(spam, "field exists, status = REMOVED"); - const_cast<StructuredFieldValue&>(*this).remove(start->getFieldRef()); + const_cast<StructuredFieldValue&>(*this).remove(fpe.getFieldRef()); return IteratorHandler::MODIFIED; } else if (status == IteratorHandler::MODIFIED) { LOG(spam, "field exists, status = MODIFIED"); - const_cast<StructuredFieldValue&>(*this).setFieldValue( - start->getFieldRef(), start->getFieldValueToSet()); + const_cast<StructuredFieldValue&>(*this).setFieldValue(fpe.getFieldRef(), fpe.getFieldValueToSet()); return IteratorHandler::MODIFIED; } else { LOG(spam, "field exists, status = %u", status); @@ -115,11 +109,10 @@ StructuredFieldValue::onIterateNested( } else if (handler.createMissingPath()) { LOG(spam, "createMissingPath is true"); IteratorHandler::ModificationStatus status - = start->getFieldValueToSet().iterateNested(start + 1, end_, handler); + = fpe.getFieldValueToSet().iterateNested(nested.next(), handler); if (status == IteratorHandler::MODIFIED) { LOG(spam, "field did not exist, status = MODIFIED"); - const_cast<StructuredFieldValue&>(*this).setFieldValue( - start->getFieldRef(), start->getFieldValueToSet()); + const_cast<StructuredFieldValue&>(*this).setFieldValue(fpe.getFieldRef(), fpe.getFieldValueToSet()); return status; } } @@ -140,8 +133,7 @@ StructuredFieldValue::onIterateNested( 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(start, end_, handler); + IteratorHandler::ModificationStatus currStatus = getValue(it.field())->iterateNested(nested, handler); if (currStatus == IteratorHandler::REMOVED) { fieldsToRemove.push_back(&it.field()); status = IteratorHandler::MODIFIED; diff --git a/document/src/vespa/document/fieldvalue/structuredfieldvalue.h b/document/src/vespa/document/fieldvalue/structuredfieldvalue.h index 90de961a603..4cccbf05de0 100644 --- a/document/src/vespa/document/fieldvalue/structuredfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/structuredfieldvalue.h @@ -31,7 +31,7 @@ class StructuredFieldValue : public FieldValue { const DataType *_type; - UP onGetNestedFieldValue(FieldPath::const_iterator start, FieldPath::const_iterator end) const override; + UP onGetNestedFieldValue(PathRange nested) const override; protected: StructuredFieldValue(const DataType &type); @@ -93,7 +93,7 @@ protected: void setFieldValue(const Field & field, const FieldValue & value); IteratorHandler::ModificationStatus - onIterateNested(FieldPath::const_iterator start, FieldPath::const_iterator end, IteratorHandler & handler) const override; + onIterateNested(PathRange nested, IteratorHandler & handler) const override; public: DECLARE_IDENTIFIABLE_ABSTRACT(StructuredFieldValue); diff --git a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp index 36f1eabce84..2bb9c1f4bc4 100644 --- a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp @@ -204,11 +204,9 @@ WeightedSetFieldValue::find(const FieldValue& key) } FieldValue::IteratorHandler::ModificationStatus -WeightedSetFieldValue::onIterateNested(FieldPath::const_iterator start, - FieldPath::const_iterator end_, - IteratorHandler & handler) const +WeightedSetFieldValue::onIterateNested(PathRange nested, IteratorHandler & handler) const { - return _map.iterateNestedImpl(start, end_, handler, *this); + return _map.iterateNestedImpl(nested, handler, *this); } } // document diff --git a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h index efa1c718d64..28517f45aee 100644 --- a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h @@ -33,10 +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( - FieldPath::const_iterator start, - FieldPath::const_iterator end, - IteratorHandler& handler) const override; + IteratorHandler::ModificationStatus onIterateNested(PathRange nested, IteratorHandler& handler) const override; public: typedef std::unique_ptr<WeightedSetFieldValue> UP; diff --git a/document/src/vespa/document/select/valuenode.cpp b/document/src/vespa/document/select/valuenode.cpp index 0552ab8b560..bc2bc249db6 100644 --- a/document/src/vespa/document/select/valuenode.cpp +++ b/document/src/vespa/document/select/valuenode.cpp @@ -241,7 +241,7 @@ FieldValueNode::getValue(const Context& context) const initFieldPath(doc.getType()); IteratorHandler handler; - doc.iterateNested(_fieldPath.begin(), _fieldPath.end(), handler); + doc.iterateNested(_fieldPath.getFullRange(), handler); if (handler.hasSingleValue()) { return handler.getSingleValue(); @@ -406,7 +406,7 @@ FieldValueNode::traceValue(const Context &context, std::ostream& out) const initFieldPath(doc.getType()); IteratorHandler handler; - doc.iterateNested(_fieldPath.begin(), _fieldPath.end(), handler); + doc.iterateNested(_fieldPath.getFullRange(), handler); if (handler.hasSingleValue()) { return handler.getSingleValue(); |