diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2022-03-22 09:49:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-22 09:49:57 +0100 |
commit | 29a9815bc0962b97ed36e80ffe9784d789365025 (patch) | |
tree | 58f36ebd93a39be8770a0b663cc0655dc394cac8 | |
parent | 4a6506e8e721d75d91e1398a876653df1e749d2b (diff) | |
parent | b35bb7fb3add35ff916cbad80a8764a4533798d1 (diff) |
Merge pull request #21715 from vespa-engine/balder/avoid-identifiable-fieldvalue
Avoid requiring identifiable for FieldValue
96 files changed, 451 insertions, 759 deletions
diff --git a/document/src/tests/arrayfieldvaluetest.cpp b/document/src/tests/arrayfieldvaluetest.cpp index 375ce05a4e6..86cd50cf965 100644 --- a/document/src/tests/arrayfieldvaluetest.cpp +++ b/document/src/tests/arrayfieldvaluetest.cpp @@ -105,7 +105,7 @@ TEST(ArrayFieldValueTest, testArray) // Iterating const ArrayFieldValue& constVal(value); for(const FieldValue & fval1 : constVal) { - EXPECT_EQ((uint32_t) IntFieldValue::classId, fval1.getClass().id()); + EXPECT_EQ(FieldValue::Type::INT, fval1.type()); } value2 = value; for(size_t i(0); i < value2.size(); i++) { diff --git a/document/src/tests/documenttestcase.cpp b/document/src/tests/documenttestcase.cpp index c852e219faa..4c97e99459e 100644 --- a/document/src/tests/documenttestcase.cpp +++ b/document/src/tests/documenttestcase.cpp @@ -50,11 +50,11 @@ TEST(DocumentTest, testSizeOf) EXPECT_EQ(32u, sizeof(vespalib::GrowableByteBuffer)); EXPECT_EQ(88ul, sizeof(IdString)); EXPECT_EQ(104ul, sizeof(DocumentId)); - EXPECT_EQ(240ul, sizeof(Document)); + EXPECT_EQ(256ul, sizeof(Document)); EXPECT_EQ(80ul, sizeof(NumericDataType)); EXPECT_EQ(24ul, sizeof(LongFieldValue)); - EXPECT_EQ(96ul, sizeof(StructFieldValue)); - EXPECT_EQ(16ul, sizeof(StructuredFieldValue)); + EXPECT_EQ(104ul, sizeof(StructFieldValue)); + EXPECT_EQ(24ul, sizeof(StructuredFieldValue)); EXPECT_EQ(56ul, sizeof(SerializableArray)); } @@ -931,48 +931,6 @@ TEST(DocumentTest, testCRC32) /// \todo TODO (was warning): Cannot test for in memory representation altered, as there is no syntax for getting internal refs to data from document. Add test when this is added. } -TEST(DocumentTest, testHasChanged) -{ - TestDocRepo test_repo; - Document doc(*test_repo.getDocumentType("testdoctype1"), - DocumentId("id:ns:testdoctype1::crawler:http://www.ntnu.no/")); - // Before deserialization we are changed. - EXPECT_TRUE(doc.hasChanged()); - - doc.setValue(doc.getField("hstringval"), StringFieldValue("bla bla bla bla bla")); - // Still changed after setting a value of course. - EXPECT_TRUE(doc.hasChanged()); - - nbostream buf; - doc.serialize(buf); - // Setting a value in doc tags us changed. - { - buf.rp(0); - Document doc2(test_repo.getTypeRepo(), buf); - EXPECT_TRUE(!doc2.hasChanged()); - - doc2.setValue("headerval", IntFieldValue::make(13)); - EXPECT_TRUE(doc2.hasChanged()); - } - // Overwriting a value in doc tags us changed. - { - buf.rp(0); - Document doc2(test_repo.getTypeRepo(), buf); - - doc2.setValue("hstringval", StringFieldValue::make("bla bla bla bla bla")); - EXPECT_TRUE(doc2.hasChanged()); - } - // Clearing value tags us changed. - { - buf.rp(0); - Document doc2(test_repo.getTypeRepo(), buf); - - doc2.clear(); - EXPECT_TRUE(doc2.hasChanged()); - } - // Add more tests here when we allow non-const refs to internals -} - TEST(DocumentTest, testSliceSerialize) { // Test that document doesn't need its own bytebuffer, such that we diff --git a/document/src/tests/documentupdatetestcase.cpp b/document/src/tests/documentupdatetestcase.cpp index 26819699db4..e1e86bca671 100644 --- a/document/src/tests/documentupdatetestcase.cpp +++ b/document/src/tests/documentupdatetestcase.cpp @@ -495,7 +495,7 @@ TEST(DocumentUpdateTest, testReadSerializedFile) const AddValueUpdate* add = static_cast<const AddValueUpdate*>(serValue); const FieldValue* value = &add->getValue(); - EXPECT_TRUE(value->inherits(FloatFieldValue::classId)); + EXPECT_TRUE(value->isA(FieldValue::Type::FLOAT)); EXPECT_FLOAT_EQ(value->getAsFloat(), 5.00f); serValue = &serField3[1]; @@ -503,7 +503,7 @@ TEST(DocumentUpdateTest, testReadSerializedFile) add = static_cast<const AddValueUpdate*>(serValue); value = &add->getValue(); - EXPECT_TRUE(value->inherits(FloatFieldValue::classId)); + EXPECT_TRUE(value->isA(FieldValue::Type::FLOAT)); EXPECT_FLOAT_EQ(value->getAsFloat(), 4.23f); serValue = &serField3[2]; @@ -511,7 +511,7 @@ TEST(DocumentUpdateTest, testReadSerializedFile) add = static_cast<const AddValueUpdate*>(serValue); value = &add->getValue(); - EXPECT_TRUE(value->inherits(FloatFieldValue::classId)); + EXPECT_TRUE(value->isA(FieldValue::Type::FLOAT)); EXPECT_FLOAT_EQ(value->getAsFloat(), -1.00f); } diff --git a/document/src/tests/fieldvalue/fieldvalue_test.cpp b/document/src/tests/fieldvalue/fieldvalue_test.cpp index d8712768000..d27877f68c3 100644 --- a/document/src/tests/fieldvalue/fieldvalue_test.cpp +++ b/document/src/tests/fieldvalue/fieldvalue_test.cpp @@ -21,7 +21,7 @@ TEST("require that StringFieldValue can be assigned primitives") { } TEST("require that FieldValues does not change their storage size.") { - EXPECT_EQUAL(8u, sizeof(FieldValue)); + EXPECT_EQUAL(16u, sizeof(FieldValue)); EXPECT_EQUAL(16u, sizeof(IntFieldValue)); EXPECT_EQUAL(24u, sizeof(LongFieldValue)); EXPECT_EQUAL(104u, sizeof(StringFieldValue)); diff --git a/document/src/tests/fieldvalue/referencefieldvalue_test.cpp b/document/src/tests/fieldvalue/referencefieldvalue_test.cpp index db380353a55..fccce30aaf8 100644 --- a/document/src/tests/fieldvalue/referencefieldvalue_test.cpp +++ b/document/src/tests/fieldvalue/referencefieldvalue_test.cpp @@ -7,7 +7,6 @@ #include <vespa/vespalib/testkit/testapp.h> #include <vespa/vespalib/util/exceptions.h> #include <ostream> -#include <sstream> using namespace document; @@ -44,14 +43,6 @@ TEST_F("Reference can be constructed with document ID", Fixture) { EXPECT_EQUAL(DocumentId("id:ns:foo::itsa-me"), fv.getDocumentId()); } -TEST_F("Newly constructed reference is marked as changed", Fixture) { - ReferenceFieldValue fv(f.refType); - EXPECT_TRUE(fv.hasChanged()); - - ReferenceFieldValue fv2(f.refType, DocumentId("id:ns:foo::itsa-me")); - EXPECT_TRUE(fv2.hasChanged()); -} - TEST_F("Exception is thrown if constructor doc ID type does not match referenced document type", Fixture) { EXPECT_EXCEPTION( ReferenceFieldValue(f.refType, DocumentId("id:ns:bar::wario-time")), @@ -78,12 +69,6 @@ TEST_F("Can explicitly assign new document ID to reference", Fixture) { EXPECT_EQUAL(f.refType, *fv.getDataType()); } -TEST_F("Assigning explicit document ID clears changed-flag", Fixture) { - ReferenceFieldValue fv(f.refType); - fv.setDeserializedDocumentId(DocumentId("id:ns:foo::yoshi-eggs")); - EXPECT_FALSE(fv.hasChanged()); -} - TEST_F("Exception is thrown if explicitly assigned doc ID does not have same type as reference target type", Fixture) { ReferenceFieldValue fv(f.refType); @@ -104,19 +89,6 @@ TEST_F("assign()ing another reference field value assigns doc ID and type", Fixt EXPECT_EQUAL(src.getDataType(), dest.getDataType()); } -// Different FieldValue subclasses actually disagree on whether this should be -// the case, e.g. LiteralFieldValue and TensorFieldValue. We go with the -// latter's approach, as that should be the most conservative one. -TEST_F("assign() marks assignee as changed", Fixture) { - ReferenceFieldValue src(f.refType, DocumentId("id:ns:foo::yoshi")); - ReferenceFieldValue dest(f.refType); - - dest.setDeserializedDocumentId(DocumentId("id:ns:foo::yoshi-eggs")); - EXPECT_FALSE(dest.hasChanged()); - - dest.assign(src); - EXPECT_TRUE(dest.hasChanged()); -} TEST_F("clone()ing creates new instance with same ID and type", Fixture) { ReferenceFieldValue src(f.refType, DocumentId("id:ns:foo::yoshi")); @@ -126,7 +98,6 @@ TEST_F("clone()ing creates new instance with same ID and type", Fixture) { ASSERT_TRUE(cloned->hasValidDocumentId()); EXPECT_EQUAL(src.getDocumentId(), cloned->getDocumentId()); EXPECT_EQUAL(src.getDataType(), cloned->getDataType()); - EXPECT_TRUE(cloned->hasChanged()); } TEST_F("Can clone() value without document ID", Fixture) { @@ -136,7 +107,6 @@ TEST_F("Can clone() value without document ID", Fixture) { ASSERT_TRUE(cloned); EXPECT_FALSE(cloned->hasValidDocumentId()); EXPECT_EQUAL(src.getDataType(), cloned->getDataType()); - EXPECT_TRUE(cloned->hasChanged()); } TEST_F("compare() orders first on type ID, then on document ID", Fixture) { diff --git a/document/src/tests/serialization/vespadocumentserializer_test.cpp b/document/src/tests/serialization/vespadocumentserializer_test.cpp index 33e8c521e09..3db001e1732 100644 --- a/document/src/tests/serialization/vespadocumentserializer_test.cpp +++ b/document/src/tests/serialization/vespadocumentserializer_test.cpp @@ -986,22 +986,6 @@ TEST_F("ReferenceFieldValue with ID can be roundtrip serialized", RefFixture) { serializeAndDeserialize(ref_with_id, stream, f.fixed_repo); } -TEST_F("Empty ReferenceFieldValue has changed-flag cleared after deserialization", RefFixture) { - ReferenceFieldValue src(f.ref_type()); - ReferenceFieldValue dest(f.ref_type()); - f.roundtrip_serialize(src, dest); - - EXPECT_FALSE(dest.hasChanged()); -} - -TEST_F("ReferenceFieldValue with ID has changed-flag cleared after deserialization", RefFixture) { - ReferenceFieldValue src(f.ref_type(), DocumentId("id:ns:" + doc_name + "::foo")); - ReferenceFieldValue dest(f.ref_type()); - f.roundtrip_serialize(src, dest); - - EXPECT_FALSE(dest.hasChanged()); -} - TEST_F("Empty ReferenceFieldValue serialization matches Java", RefFixture) { ReferenceFieldValue value(f.ref_type()); f.verify_cross_language_serialization("empty_reference", value); diff --git a/document/src/tests/weightedsetfieldvaluetest.cpp b/document/src/tests/weightedsetfieldvaluetest.cpp index 61f727120d1..4cc897f22d7 100644 --- a/document/src/tests/weightedsetfieldvaluetest.cpp +++ b/document/src/tests/weightedsetfieldvaluetest.cpp @@ -141,8 +141,7 @@ TEST(WeightedSetFieldValueTest, testWeightedSet) { const FieldValue& fval1(*it->first); (void) fval1; - EXPECT_EQ((uint32_t) IntFieldValue::classId, - it->first->getClass().id()); + EXPECT_TRUE(it->first->isA(FieldValue::Type::INT)); const IntFieldValue& val = dynamic_cast<const IntFieldValue&>(*it->second); (void) val; } diff --git a/document/src/vespa/document/base/fieldpath.cpp b/document/src/vespa/document/base/fieldpath.cpp index 5da64272364..fcac59847cb 100644 --- a/document/src/vespa/document/base/fieldpath.cpp +++ b/document/src/vespa/document/base/fieldpath.cpp @@ -5,7 +5,6 @@ #include <vespa/document/datatype/mapdatatype.h> #include <vespa/vespalib/util/exceptions.h> #include <vespa/document/fieldvalue/fieldvalue.h> -#include <vespa/vespalib/objects/visit.hpp> using vespalib::IllegalArgumentException; using vespalib::make_string; @@ -127,17 +126,6 @@ FieldPathEntry::stealFieldValueToSet() const return FieldValue::UP(_fillInVal.release()); } -void -FieldPathEntry::visitMembers(vespalib::ObjectVisitor &visitor) const -{ - visit(visitor, "type", _type); - visit(visitor, "name", _name); - visit(visitor, "lookupIndex", _lookupIndex); - visit(visitor, "lookupKey", _lookupKey); - visit(visitor, "variableName", _variableName); - visit(visitor, "fillInVal", _fillInVal); -} - vespalib::string FieldPathEntry::parseKey(vespalib::stringref & key) { @@ -191,7 +179,8 @@ FieldPath::FieldPath(const FieldPath &) = default; FieldPath & FieldPath::operator=(const FieldPath &) = default; FieldPath::~FieldPath() = default; -FieldPath::iterator FieldPath::insert(iterator pos, std::unique_ptr<FieldPathEntry> entry) { +FieldPath::iterator +FieldPath::insert(iterator pos, std::unique_ptr<FieldPathEntry> entry) { return _path.insert(pos, vespalib::CloneablePtr<FieldPathEntry>(entry.release())); } void FieldPath::push_back(std::unique_ptr<FieldPathEntry> entry) { _path.emplace_back(entry.release()); } @@ -199,13 +188,4 @@ void FieldPath::pop_back() { _path.pop_back(); } void FieldPath::clear() { _path.clear(); } void FieldPath::reserve(size_t sz) { _path.reserve(sz); } -void -FieldPath::visitMembers(vespalib::ObjectVisitor& visitor) const -{ - (void) visitor; - for (uint32_t i = 0; i < _path.size(); ++i) { -// visit(visitor, vespalib::make_string("[%u]", i), _path[i]); - } -} - } diff --git a/document/src/vespa/document/base/fieldpath.h b/document/src/vespa/document/base/fieldpath.h index 679fd0885dd..a79e4595a61 100644 --- a/document/src/vespa/document/base/fieldpath.h +++ b/document/src/vespa/document/base/fieldpath.h @@ -2,10 +2,7 @@ #pragma once #include "field.h" -#include <vespa/document/util/identifiableid.h> -#include <vector> - -namespace vespalib { class ObjectVisitor; } +#include <vespa/vespalib/util/memory.h> namespace document { @@ -80,7 +77,6 @@ public: FieldValue * getFieldValueToSetPtr() const { return _fillInVal.get(); } FieldValue & getFieldValueToSet() const { return *_fillInVal; } std::unique_ptr<FieldValue> stealFieldValueToSet() const; - void visitMembers(vespalib::ObjectVisitor &visitor) const; /** * Parses a string of the format {["]escaped string["]} to its unescaped value. * @param key is the incoming value, and contains what is left when done. @@ -115,8 +111,8 @@ public: FieldPath(); FieldPath(const FieldPath &); FieldPath & operator=(const FieldPath &); - FieldPath(FieldPath &&) = default; - FieldPath & operator=(FieldPath &&) = default; + FieldPath(FieldPath &&) noexcept = default; + FieldPath & operator=(FieldPath &&) noexcept = default; ~FieldPath(); template <typename InputIterator> @@ -151,8 +147,6 @@ public: const FieldPathEntry & operator[](Container::size_type i) const { return *_path[i]; } - void visitMembers(vespalib::ObjectVisitor &visitor) const; - template <typename IT> class Range { public: diff --git a/document/src/vespa/document/datatype/datatype.cpp b/document/src/vespa/document/datatype/datatype.cpp index 87464a197ee..3cc7034e336 100644 --- a/document/src/vespa/document/datatype/datatype.cpp +++ b/document/src/vespa/document/datatype/datatype.cpp @@ -51,32 +51,32 @@ class DataType2FieldValueId { public: DataType2FieldValueId(); - unsigned int getFieldValueId(unsigned int id) const { + FieldValue::Type getFieldValueId(unsigned int id) const { return id < sizeof(_type2FieldValueId)/sizeof(_type2FieldValueId[0]) ? _type2FieldValueId[id] - : 0; + : FieldValue::Type::NONE; } private: - unsigned int _type2FieldValueId[DataType::MAX]; + FieldValue::Type _type2FieldValueId[DataType::MAX]; }; DataType2FieldValueId::DataType2FieldValueId() { for (size_t i(0); i < sizeof(_type2FieldValueId)/sizeof(_type2FieldValueId[0]); i++) { - _type2FieldValueId[i] = 0; + _type2FieldValueId[i] = FieldValue::Type::NONE; } - _type2FieldValueId[DataType::T_BYTE] = ByteFieldValue::classId; - _type2FieldValueId[DataType::T_SHORT] = ShortFieldValue::classId; - _type2FieldValueId[DataType::T_INT] = IntFieldValue::classId; - _type2FieldValueId[DataType::T_LONG] = LongFieldValue::classId; - _type2FieldValueId[DataType::T_FLOAT] = FloatFieldValue::classId; - _type2FieldValueId[DataType::T_DOUBLE] = DoubleFieldValue::classId; - _type2FieldValueId[DataType::T_BOOL] = BoolFieldValue::classId; - _type2FieldValueId[DataType::T_STRING] = StringFieldValue::classId; - _type2FieldValueId[DataType::T_RAW] = RawFieldValue::classId; - _type2FieldValueId[DataType::T_URI] = StringFieldValue::classId; - _type2FieldValueId[DataType::T_PREDICATE] = PredicateFieldValue::classId; - _type2FieldValueId[DataType::T_TENSOR] = TensorFieldValue::classId; + _type2FieldValueId[DataType::T_BYTE] = FieldValue::Type::BYTE; + _type2FieldValueId[DataType::T_SHORT] = FieldValue::Type::SHORT; + _type2FieldValueId[DataType::T_INT] = FieldValue::Type::INT; + _type2FieldValueId[DataType::T_LONG] = FieldValue::Type::LONG; + _type2FieldValueId[DataType::T_FLOAT] = FieldValue::Type::FLOAT; + _type2FieldValueId[DataType::T_DOUBLE] = FieldValue::Type::DOUBLE; + _type2FieldValueId[DataType::T_BOOL] = FieldValue::Type::BOOL; + _type2FieldValueId[DataType::T_STRING] = FieldValue::Type::STRING; + _type2FieldValueId[DataType::T_RAW] = FieldValue::Type::RAW; + _type2FieldValueId[DataType::T_URI] = FieldValue::Type::STRING; + _type2FieldValueId[DataType::T_PREDICATE] = FieldValue::Type::PREDICATE; + _type2FieldValueId[DataType::T_TENSOR] = FieldValue::Type::TENSOR; } DataType2FieldValueId _G_type2FieldValueId; @@ -86,9 +86,8 @@ DataType2FieldValueId _G_type2FieldValueId; bool DataType::isValueType(const FieldValue & fv) const { if ((_dataTypeId >= 0) && _dataTypeId < MAX) { - const uint32_t cid(_G_type2FieldValueId.getFieldValueId(_dataTypeId)); - if (cid != 0) { - return cid == fv.getClass().id(); + if (fv.isA(_G_type2FieldValueId.getFieldValueId(_dataTypeId))) { + return true; } } return _dataTypeId == fv.getDataType()->getId(); diff --git a/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.cpp b/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.cpp index e26f0f15759..130e68a9f54 100644 --- a/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.cpp @@ -9,12 +9,6 @@ using std::string; namespace document { -AnnotationReferenceFieldValue::AnnotationReferenceFieldValue( - const DataType &type, int32_t annotation_index) - : _type(&type), - _annotation_index(annotation_index) { -} - int AnnotationReferenceFieldValue::compare(const FieldValue &other) const { if (getDataType()->equals(*other.getDataType())) { const AnnotationReferenceFieldValue &val(static_cast<const AnnotationReferenceFieldValue &>(other)); @@ -35,8 +29,4 @@ void AnnotationReferenceFieldValue::printXml(XmlOutputStream &out) const { out << _annotation_index; } -bool AnnotationReferenceFieldValue::hasChanged() const { - return false; -} - } // namespace document diff --git a/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.h b/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.h index 6fc85bf384f..732be94c5c8 100644 --- a/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.h +++ b/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.h @@ -9,15 +9,17 @@ namespace document { class Annotation; class AnnotationReferenceDataType; -class AnnotationReferenceFieldValue : public FieldValue { +class AnnotationReferenceFieldValue final : public FieldValue { const DataType *_type; int32_t _annotation_index; public: AnnotationReferenceFieldValue(const DataType &type) - : _type(&type), _annotation_index(0) {} - AnnotationReferenceFieldValue(const DataType &type, - int32_t annotation_index); + : AnnotationReferenceFieldValue(type, 0) {} + AnnotationReferenceFieldValue(const DataType &type, int32_t annotation_index) + : FieldValue(Type::ANNOTATION_REFERENCE), _type(&type), _annotation_index(annotation_index) + {} + void setAnnotationIndex(int32_t index) { _annotation_index = index; } void accept(FieldValueVisitor &visitor) override { visitor.visit(*this); } @@ -30,7 +32,6 @@ public: AnnotationReferenceFieldValue *clone() const override; const DataType *getDataType() const override { return _type; } void printXml(XmlOutputStream &out) const override; - bool hasChanged() const override; }; } // namespace document diff --git a/document/src/vespa/document/fieldvalue/arrayfieldvalue.cpp b/document/src/vespa/document/fieldvalue/arrayfieldvalue.cpp index 07f731a9ea7..51bc42d2cee 100644 --- a/document/src/vespa/document/fieldvalue/arrayfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/arrayfieldvalue.cpp @@ -23,10 +23,8 @@ using fieldvalue::ModificationStatus; using fieldvalue::IteratorHandler; using fieldvalue::VariableMap; -IMPLEMENT_IDENTIFIABLE_ABSTRACT(ArrayFieldValue, CollectionFieldValue); - ArrayFieldValue::ArrayFieldValue(const DataType &type) - : CollectionFieldValue(type), + : CollectionFieldValue(Type::ARRAY, type), _array() { _array.reset(static_cast<IArray *>(createArray(getNestedType()).release())); @@ -170,15 +168,6 @@ ArrayFieldValue::print(std::ostream& out, bool verbose, out << "\n" << indent << ")"; } -bool -ArrayFieldValue::hasChanged() const -{ - for (uint32_t i=0, n=_array->size(); i<n; ++i) { - if (array()[i].hasChanged()) return true; - } - return false; -} - fieldvalue::ModificationStatus ArrayFieldValue::iterateSubset(int startPos, int endPos, vespalib::stringref variable, diff --git a/document/src/vespa/document/fieldvalue/arrayfieldvalue.h b/document/src/vespa/document/fieldvalue/arrayfieldvalue.h index c4f879f7348..ae6aea47c2c 100644 --- a/document/src/vespa/document/fieldvalue/arrayfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/arrayfieldvalue.h @@ -18,7 +18,7 @@ namespace document { -class ArrayFieldValue : public CollectionFieldValue { +class ArrayFieldValue final : public CollectionFieldValue { private: using IArray = vespalib::IArrayT<FieldValue>; std::unique_ptr<IArray> _array; @@ -68,14 +68,12 @@ public: int compare(const FieldValue&) const override; void printXml(XmlOutputStream& out) const override; void print(std::ostream& out, bool verbose, const std::string& indent) const override; - bool hasChanged() const override; void swap(ArrayFieldValue & other) { _array.swap(other._array); } // Iterator functionality const_iterator begin() const { return array().begin(); } const_iterator end() const { return array().end(); } - DECLARE_IDENTIFIABLE_ABSTRACT(ArrayFieldValue); private: iterator begin() { return array().begin(); } iterator end() { return array().end(); } diff --git a/document/src/vespa/document/fieldvalue/boolfieldvalue.cpp b/document/src/vespa/document/fieldvalue/boolfieldvalue.cpp index 1c5261877fd..bbd40623267 100644 --- a/document/src/vespa/document/fieldvalue/boolfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/boolfieldvalue.cpp @@ -9,36 +9,37 @@ using namespace vespalib::xml; namespace document { -IMPLEMENT_IDENTIFIABLE(BoolFieldValue, FieldValue); - BoolFieldValue::BoolFieldValue(bool value) - : _value(value), _altered(false) { + : FieldValue(Type::BOOL), _value(value) { } BoolFieldValue::~BoolFieldValue() = default; -FieldValue &BoolFieldValue::assign(const FieldValue &rhs) { - if (rhs.inherits(BoolFieldValue::classId)) { +FieldValue & +BoolFieldValue::assign(const FieldValue &rhs) { + if (rhs.isA(Type::BOOL)) { operator=(static_cast<const BoolFieldValue &>(rhs)); return *this; } else { - _altered = true; return FieldValue::assign(rhs); } } -int BoolFieldValue::compare(const FieldValue&rhs) const { +int +BoolFieldValue::compare(const FieldValue&rhs) const { int diff = FieldValue::compare(rhs); if (diff != 0) return diff; const BoolFieldValue &o = static_cast<const BoolFieldValue &>(rhs); return (_value == o._value) ? 0 : _value ? 1 : -1; } -void BoolFieldValue::printXml(XmlOutputStream& out) const { +void +BoolFieldValue::printXml(XmlOutputStream& out) const { out << XmlContent(getAsString()); } -void BoolFieldValue::print(std::ostream& out, bool, const std::string&) const { +void +BoolFieldValue::print(std::ostream& out, bool, const std::string&) const { out << (_value ? "true" : "false") << "\n"; } @@ -47,11 +48,6 @@ BoolFieldValue::getDataType() const { return DataType::BOOL; } -bool -BoolFieldValue::hasChanged() const { - return _altered; -} - FieldValue * BoolFieldValue::clone() const { return new BoolFieldValue(*this); diff --git a/document/src/vespa/document/fieldvalue/boolfieldvalue.h b/document/src/vespa/document/fieldvalue/boolfieldvalue.h index 01cfcf2cd48..0265205665d 100644 --- a/document/src/vespa/document/fieldvalue/boolfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/boolfieldvalue.h @@ -9,9 +9,8 @@ namespace document { /** * Represent the value in a field of type 'bool' which can be either true or false. **/ -class BoolFieldValue : public FieldValue { +class BoolFieldValue final : public FieldValue { bool _value; - bool _altered; public: BoolFieldValue(bool value=false); @@ -27,7 +26,6 @@ public: void print(std::ostream &out, bool verbose, const std::string &indent) const override; const DataType *getDataType() const override; - bool hasChanged() const override; bool getValue() const { return _value; } void setValue(bool v) { _value = v; } @@ -42,7 +40,6 @@ public: vespalib::string getAsString() const override; BoolFieldValue& operator=(vespalib::stringref) override; - DECLARE_IDENTIFIABLE(BoolFieldValue); static std::unique_ptr<BoolFieldValue> make(bool value=false) { return std::make_unique<BoolFieldValue>(value); } }; diff --git a/document/src/vespa/document/fieldvalue/bytefieldvalue.cpp b/document/src/vespa/document/fieldvalue/bytefieldvalue.cpp index 5d514352302..fff07d9de4e 100644 --- a/document/src/vespa/document/fieldvalue/bytefieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/bytefieldvalue.cpp @@ -5,6 +5,4 @@ namespace document { -IMPLEMENT_IDENTIFIABLE(ByteFieldValue, NumericFieldValueBase); - } // document diff --git a/document/src/vespa/document/fieldvalue/bytefieldvalue.h b/document/src/vespa/document/fieldvalue/bytefieldvalue.h index 2cccf483c84..1b810828c53 100644 --- a/document/src/vespa/document/fieldvalue/bytefieldvalue.h +++ b/document/src/vespa/document/fieldvalue/bytefieldvalue.h @@ -12,12 +12,12 @@ namespace document { -class ByteFieldValue : public NumericFieldValue<int8_t> { +class ByteFieldValue final : public NumericFieldValue<int8_t> { public: typedef int8_t Number; ByteFieldValue(Number value = 0) - : NumericFieldValue<Number>(value) {} + : NumericFieldValue<Number>(Type::BYTE, value) {} void accept(FieldValueVisitor &visitor) override { visitor.visit(*this); } void accept(ConstFieldValueVisitor &visitor) const override { visitor.visit(*this); } @@ -25,7 +25,6 @@ public: ByteFieldValue* clone() const override { return new ByteFieldValue(*this); } using NumericFieldValue<Number>::operator=; - DECLARE_IDENTIFIABLE(ByteFieldValue); static std::unique_ptr<ByteFieldValue> make(Number value=0) { return std::make_unique<ByteFieldValue>(value); } }; diff --git a/document/src/vespa/document/fieldvalue/collectionfieldvalue.cpp b/document/src/vespa/document/fieldvalue/collectionfieldvalue.cpp index 4c960502b71..b9400a1e663 100644 --- a/document/src/vespa/document/fieldvalue/collectionfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/collectionfieldvalue.cpp @@ -5,7 +5,6 @@ namespace document { -IMPLEMENT_IDENTIFIABLE_ABSTRACT(CollectionFieldValue, FieldValue); CollectionFieldValue::CollectionFieldValue(const CollectionFieldValue& other) : FieldValue(other), diff --git a/document/src/vespa/document/fieldvalue/collectionfieldvalue.h b/document/src/vespa/document/fieldvalue/collectionfieldvalue.h index 9efd3b91bc6..d4a1367bee2 100644 --- a/document/src/vespa/document/fieldvalue/collectionfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/collectionfieldvalue.h @@ -27,9 +27,9 @@ protected: void verifyType(const CollectionFieldValue& other) const; public: - CollectionFieldValue(const DataType &type) - : FieldValue(), - _type(&type) + CollectionFieldValue(Type type, const DataType &dataType) + : FieldValue(type), + _type(&dataType) {} CollectionFieldValue(const CollectionFieldValue& other); @@ -61,8 +61,6 @@ public: virtual bool isEmpty() const = 0; virtual size_t size() const = 0; virtual void clear() = 0; - - DECLARE_IDENTIFIABLE_ABSTRACT(CollectionFieldValue); }; } diff --git a/document/src/vespa/document/fieldvalue/document.cpp b/document/src/vespa/document/fieldvalue/document.cpp index 57787738502..0cd1faa5d62 100644 --- a/document/src/vespa/document/fieldvalue/document.cpp +++ b/document/src/vespa/document/fieldvalue/document.cpp @@ -65,10 +65,8 @@ Document::setType(const DataType & type) { _fields.setType(getType().getFieldsType()); } -IMPLEMENT_IDENTIFIABLE_ABSTRACT(Document, StructuredFieldValue); - Document::Document() - : StructuredFieldValue(*DataType::DOCUMENT), + : StructuredFieldValue(Type::DOCUMENT, *DataType::DOCUMENT), _id(), _fields(getType().getFieldsType()), _backingBuffer(), @@ -86,7 +84,7 @@ Document::Document(const Document& rhs) {} Document::Document(const DataType &type, DocumentId documentId) - : StructuredFieldValue(verifyDocumentType(&type)), + : StructuredFieldValue(Type::DOCUMENT, verifyDocumentType(&type)), _id(std::move(documentId)), _fields(getType().getFieldsType()), _backingBuffer(), @@ -104,7 +102,7 @@ void Document::setRepo(const DocumentTypeRepo& repo) } Document::Document(const DocumentTypeRepo& repo, vespalib::nbostream & is) - : StructuredFieldValue(*DataType::DOCUMENT), + : StructuredFieldValue(Type::DOCUMENT, *DataType::DOCUMENT), _id(), _fields(static_cast<const DocumentType &>(getType()).getFieldsType()), _backingBuffer(), @@ -114,7 +112,7 @@ Document::Document(const DocumentTypeRepo& repo, vespalib::nbostream & is) } Document::Document(const DocumentTypeRepo& repo, vespalib::DataBuffer && backingBuffer) - : StructuredFieldValue(*DataType::DOCUMENT), + : StructuredFieldValue(Type::DOCUMENT, *DataType::DOCUMENT), _id(), _fields(static_cast<const DocumentType &>(getType()).getFieldsType()), _backingBuffer(), @@ -173,12 +171,6 @@ Document::setFieldValue(const Field& field, FieldValue::UP data) _fields.setFieldValue(field, std::move(data)); } -bool -Document::hasChanged() const -{ - return _fields.hasChanged(); -} - FieldValue& Document::assign(const FieldValue& value) { diff --git a/document/src/vespa/document/fieldvalue/document.h b/document/src/vespa/document/fieldvalue/document.h index da6bcca777c..610b2fcbd1b 100644 --- a/document/src/vespa/document/fieldvalue/document.h +++ b/document/src/vespa/document/fieldvalue/document.h @@ -24,7 +24,7 @@ namespace document { class TransactionGuard; -class Document : public StructuredFieldValue +class Document final : public StructuredFieldValue { private: DocumentId _id; @@ -86,8 +86,6 @@ public: void clear() override; - bool hasChanged() const override; - // FieldValue implementation. FieldValue& assign(const FieldValue&) override; int compare(const FieldValue& other) const override; @@ -109,9 +107,6 @@ public: bool empty() const override { return _fields.empty(); } uint32_t calculateChecksum() const; - - DECLARE_IDENTIFIABLE_ABSTRACT(Document); - void setFieldValue(const Field& field, FieldValue::UP data) override; private: friend TransactionGuard; diff --git a/document/src/vespa/document/fieldvalue/doublefieldvalue.cpp b/document/src/vespa/document/fieldvalue/doublefieldvalue.cpp index 943255e5ffc..3ab255be8db 100644 --- a/document/src/vespa/document/fieldvalue/doublefieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/doublefieldvalue.cpp @@ -5,6 +5,5 @@ namespace document { -IMPLEMENT_IDENTIFIABLE(DoubleFieldValue, NumericFieldValueBase); } // document diff --git a/document/src/vespa/document/fieldvalue/doublefieldvalue.h b/document/src/vespa/document/fieldvalue/doublefieldvalue.h index b9b20bbd24a..56ba6e334e9 100644 --- a/document/src/vespa/document/fieldvalue/doublefieldvalue.h +++ b/document/src/vespa/document/fieldvalue/doublefieldvalue.h @@ -12,11 +12,11 @@ namespace document { -class DoubleFieldValue : public NumericFieldValue<double> { +class DoubleFieldValue final : public NumericFieldValue<double> { public: typedef double Number; - DoubleFieldValue(Number value = 0) : NumericFieldValue<Number>(value) {} + DoubleFieldValue(Number value = 0) : NumericFieldValue<Number>(Type::DOUBLE, value) {} void accept(FieldValueVisitor &visitor) override { visitor.visit(*this); } void accept(ConstFieldValueVisitor &visitor) const override { visitor.visit(*this); } @@ -25,7 +25,6 @@ public: DoubleFieldValue* clone() const override { return new DoubleFieldValue(*this); } using NumericFieldValue<Number>::operator=; - DECLARE_IDENTIFIABLE(DoubleFieldValue); static std::unique_ptr<DoubleFieldValue> make(Number value=0) { return std::make_unique<DoubleFieldValue>(value); } }; diff --git a/document/src/vespa/document/fieldvalue/fieldvalue.cpp b/document/src/vespa/document/fieldvalue/fieldvalue.cpp index cc55775d54c..79cc2daafce 100644 --- a/document/src/vespa/document/fieldvalue/fieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/fieldvalue.cpp @@ -26,8 +26,50 @@ namespace document { using namespace fieldvalue; -IMPLEMENT_IDENTIFIABLE_ABSTRACT(FieldValue, vespalib::Identifiable); - +const char * +FieldValue::className() const noexcept { + switch (type()) { + case Type::BOOL: + return "BoolFieldValue"; + case Type::BYTE: + return "ByteFieldValue"; + case Type::SHORT: + return "ShortFieldValue"; + case Type::INT: + return "IntFieldValue"; + case Type::LONG: + return "LongFieldValue"; + case Type::FLOAT: + return "FloatFieldValue"; + case Type::DOUBLE: + return "DoubleFieldValue"; + case Type::STRING: + return "StringFieldValue"; + case Type::RAW: + return "RawFieldValue"; + case Type::PREDICATE: + return "PredicateFieldValue"; + case Type::TENSOR: + return "TensorFieldValue"; + case Type::ANNOTATION_REFERENCE: + return "AnnotationReferenceFieldValue"; + case Type::REFERENCE: + return "ReferenceFieldValue"; + case Type::ARRAY: + return "ArrayFieldValue"; + case Type::WSET: + return "WSetFieldValue"; + case Type::MAP: + return "MapFieldValue"; + case Type::STRUCT: + return "StructFieldValue"; + case Type::DOCUMENT: + return "DocumentFieldValue"; + case Type::NONE: + default: + abort(); + } +} void FieldValue::serialize(nbostream &stream) const { VespaDocumentSerializer serializer(stream); serializer.write(*this); diff --git a/document/src/vespa/document/fieldvalue/fieldvalue.h b/document/src/vespa/document/fieldvalue/fieldvalue.h index 5eadb3307b5..a45e42539ee 100644 --- a/document/src/vespa/document/fieldvalue/fieldvalue.h +++ b/document/src/vespa/document/fieldvalue/fieldvalue.h @@ -13,38 +13,35 @@ #include "fieldvaluevisitor.h" #include "modificationstatus.h" -#include <vespa/document/util/xmlserializable.h> +#include <vespa/document/util/identifiableid.h> #include <vespa/document/base/fieldpath.h> #include <vespa/vespalib/objects/identifiable.h> #include <vespa/vespalib/util/polymorphicarraybase.h> namespace vespalib { class nbostream; } +namespace vespalib::xml { class XmlOutputStream; } -namespace document { +namespace document::fieldvalue { class IteratorHandler; } -namespace fieldvalue { class IteratorHandler; } +namespace document { class DataType; -class FieldValue : public vespalib::Identifiable +class FieldValue { -protected: - FieldValue(const FieldValue&) = default; - FieldValue& operator=(const FieldValue&) = default; - FieldValue(FieldValue &&) = default; - FieldValue& operator=(FieldValue &&) = default; - static std::unique_ptr<vespalib::IArrayBase> createArray(const DataType & baseType); - public: + enum class Type : uint8_t { + NONE, BOOL, BYTE, SHORT, INT, LONG, FLOAT, DOUBLE, + STRING, RAW, PREDICATE, TENSOR, ANNOTATION_REFERENCE, + REFERENCE, ARRAY, WSET, MAP, STRUCT, DOCUMENT + }; using PathRange = FieldPath::Range<FieldPath::const_iterator>; using UP = std::unique_ptr<FieldValue>; using SP = std::shared_ptr<FieldValue>; using CP = vespalib::CloneablePtr<FieldValue>; + using XmlOutputStream = vespalib::xml::XmlOutputStream; - DECLARE_IDENTIFIABLE_ABSTRACT(FieldValue); - - FieldValue() = default; - + virtual ~FieldValue() = default; /** * Visit this fieldvalue for double dispatch. */ @@ -82,13 +79,6 @@ public: */ virtual int fastCompare(const FieldValue& other) const; - /** - * Returns true if this object have been altered since last - * serialization/deserialization. If hasChanged() is false, then cached - * information from last serialization effort is still valid. - */ - virtual bool hasChanged() const = 0; - /** Cloneable implementation */ virtual FieldValue* clone() const = 0; @@ -174,6 +164,27 @@ public: // Utility functions to set commonly used value types. virtual FieldValue& operator=(vespalib::stringref); + + Type type() const noexcept { return _type; } + bool isA(Type type) const noexcept { return type == _type; } + bool isCollection() const noexcept { return (_type == Type::WSET) || (_type == Type::ARRAY); } + bool isStructured() const noexcept { return (_type == Type::DOCUMENT) || (_type == Type::STRUCT); } + bool isLiteral() const noexcept { return (_type == Type::STRING) || (_type == Type::RAW); } + bool isNumeric() const noexcept { + return (_type == Type::BYTE) || (_type == Type::SHORT) || + (_type == Type::INT) || (_type == Type::LONG) || (_type == Type::FLOAT) || (_type == Type::DOUBLE); + } + bool isFixedSizeSingleValue() const noexcept { + return (_type == Type::BOOL) || isNumeric(); + } + const char * className() const noexcept; +protected: + FieldValue(Type type) noexcept : _type(type) { } + FieldValue(const FieldValue&) = default; + FieldValue& operator=(const FieldValue&) = default; + FieldValue(FieldValue &&) noexcept = default; + FieldValue& operator=(FieldValue &&) noexcept = default; + static std::unique_ptr<vespalib::IArrayBase> createArray(const DataType & baseType); private: fieldvalue::ModificationStatus iterateNested(FieldPath::const_iterator start, FieldPath::const_iterator end, fieldvalue::IteratorHandler & handler) const { @@ -181,10 +192,12 @@ private: } virtual FieldValue::UP onGetNestedFieldValue(PathRange nested) const; virtual fieldvalue::ModificationStatus onIterateNested(PathRange nested, fieldvalue::IteratorHandler & handler) const; + + Type _type; }; std::ostream& operator<<(std::ostream& out, const FieldValue & p); -XmlOutputStream & operator<<(XmlOutputStream & out, const FieldValue & p); +vespalib::xml::XmlOutputStream & operator<<(vespalib::xml::XmlOutputStream & out, const FieldValue & p); } // document diff --git a/document/src/vespa/document/fieldvalue/floatfieldvalue.cpp b/document/src/vespa/document/fieldvalue/floatfieldvalue.cpp index e44f36295c4..b3698841667 100644 --- a/document/src/vespa/document/fieldvalue/floatfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/floatfieldvalue.cpp @@ -5,6 +5,4 @@ namespace document { -IMPLEMENT_IDENTIFIABLE(FloatFieldValue, NumericFieldValueBase); - } // document diff --git a/document/src/vespa/document/fieldvalue/floatfieldvalue.h b/document/src/vespa/document/fieldvalue/floatfieldvalue.h index f662c400633..783459dec64 100644 --- a/document/src/vespa/document/fieldvalue/floatfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/floatfieldvalue.h @@ -12,11 +12,11 @@ namespace document { -class FloatFieldValue : public NumericFieldValue<float> { +class FloatFieldValue final : public NumericFieldValue<float> { public: typedef float Number; - FloatFieldValue(Number value = 0) : NumericFieldValue<Number>(value) {} + FloatFieldValue(Number value = 0) : NumericFieldValue<Number>(Type::FLOAT, value) {} void accept(FieldValueVisitor &visitor) override { visitor.visit(*this); } void accept(ConstFieldValueVisitor &visitor) const override { visitor.visit(*this); } @@ -25,7 +25,6 @@ public: FloatFieldValue* clone() const override { return new FloatFieldValue(*this); } using NumericFieldValue<Number>::operator=; - DECLARE_IDENTIFIABLE(FloatFieldValue); static std::unique_ptr<FloatFieldValue> make(Number value = 0) { return std::make_unique<FloatFieldValue>(value); } }; diff --git a/document/src/vespa/document/fieldvalue/intfieldvalue.cpp b/document/src/vespa/document/fieldvalue/intfieldvalue.cpp index 06edafcf374..42884c9fc8b 100644 --- a/document/src/vespa/document/fieldvalue/intfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/intfieldvalue.cpp @@ -5,6 +5,5 @@ namespace document { -IMPLEMENT_IDENTIFIABLE(IntFieldValue, NumericFieldValueBase); } // document diff --git a/document/src/vespa/document/fieldvalue/intfieldvalue.h b/document/src/vespa/document/fieldvalue/intfieldvalue.h index d365e34779e..521aced292c 100644 --- a/document/src/vespa/document/fieldvalue/intfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/intfieldvalue.h @@ -12,11 +12,11 @@ namespace document { -class IntFieldValue : public NumericFieldValue<int32_t> { +class IntFieldValue final : public NumericFieldValue<int32_t> { public: typedef int32_t Number; - IntFieldValue(Number value = 0) : NumericFieldValue<Number>(value) {} + IntFieldValue(Number value = 0) : NumericFieldValue<Number>(Type::INT, value) {} void accept(FieldValueVisitor &visitor) override { visitor.visit(*this); } void accept(ConstFieldValueVisitor &visitor) const override { visitor.visit(*this); } @@ -25,7 +25,6 @@ public: IntFieldValue* clone() const override { return new IntFieldValue(*this); } using NumericFieldValue<Number>::operator=; - DECLARE_IDENTIFIABLE(IntFieldValue); static std::unique_ptr<IntFieldValue> make(Number value=0) { return std::make_unique<IntFieldValue>(value); } }; diff --git a/document/src/vespa/document/fieldvalue/literalfieldvalue.cpp b/document/src/vespa/document/fieldvalue/literalfieldvalue.cpp index 7ba537d9cc2..02ad759fb8c 100644 --- a/document/src/vespa/document/fieldvalue/literalfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/literalfieldvalue.cpp @@ -8,13 +8,10 @@ using namespace vespalib::xml; namespace document { -IMPLEMENT_IDENTIFIABLE_ABSTRACT(LiteralFieldValueB, FieldValue); - -LiteralFieldValueB::LiteralFieldValueB() : - FieldValue(), +LiteralFieldValueB::LiteralFieldValueB(Type type) : + FieldValue(type), _value(), - _backing(), - _altered(true) + _backing() { _value = _backing; } @@ -24,17 +21,15 @@ LiteralFieldValueB::~LiteralFieldValueB() = default; LiteralFieldValueB::LiteralFieldValueB(const LiteralFieldValueB& other) : FieldValue(other), _value(), - _backing(other.getValueRef()), - _altered(other._altered) + _backing(other.getValueRef()) { _value = _backing; } -LiteralFieldValueB::LiteralFieldValueB(const stringref & value) - : FieldValue(), +LiteralFieldValueB::LiteralFieldValueB(Type type, const stringref & value) + : FieldValue(type), _value(), - _backing(value), - _altered(true) + _backing(value) { _value = _backing; } @@ -45,7 +40,6 @@ LiteralFieldValueB::operator=(const LiteralFieldValueB& other) FieldValue::operator=(other); _backing = other.getValueRef(); _value = _backing; - _altered = other._altered; return *this; } @@ -115,7 +109,7 @@ LiteralFieldValueB::syncBacking() const _value = _backing; } -template class LiteralFieldValue<RawFieldValue, DataType::T_RAW, false>; -template class LiteralFieldValue<StringFieldValue, DataType::T_STRING, true>; +template class LiteralFieldValue<RawFieldValue, DataType::T_RAW>; +template class LiteralFieldValue<StringFieldValue, DataType::T_STRING>; } // namespace document diff --git a/document/src/vespa/document/fieldvalue/literalfieldvalue.h b/document/src/vespa/document/fieldvalue/literalfieldvalue.h index 6e3f0223b20..89f2f6afd74 100644 --- a/document/src/vespa/document/fieldvalue/literalfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/literalfieldvalue.h @@ -24,15 +24,14 @@ class LiteralFieldValueB : public FieldValue { public: typedef vespalib::string string; typedef vespalib::stringref stringref; - DECLARE_IDENTIFIABLE_ABSTRACT(LiteralFieldValueB); typedef std::unique_ptr<LiteralFieldValueB> UP; typedef string value_type; - LiteralFieldValueB(); + explicit LiteralFieldValueB(Type type); ~LiteralFieldValueB(); LiteralFieldValueB(const LiteralFieldValueB &); - LiteralFieldValueB(const stringref & value); + LiteralFieldValueB(Type type, const stringref & value); const value_type & getValue() const { sync(); return _backing; } /** @@ -46,13 +45,11 @@ public: void setValueRef(stringref value) { _value = value; - _altered = true; } void setValue(stringref value) { _backing = value; _value = _backing; - _altered = true; } size_t hash() const override final { return vespalib::hashValue(_value.data(), _value.size()); } void setValue(const char* val, size_t size) { setValue(stringref(val, size)); } @@ -66,7 +63,6 @@ public: void printXml(XmlOutputStream& out) const override; void print(std::ostream& out, bool verbose, const std::string& indent) const override; FieldValue& assign(const FieldValue&) override; - bool hasChanged() const override{ return _altered; } FieldValue& operator=(vespalib::stringref) override; protected: @@ -78,25 +74,18 @@ protected: } mutable stringref _value; mutable string _backing; // Lazily set when needed - mutable bool _altered; // Set if altered after deserialization -private: - virtual bool getAddZeroTerm() const = 0; }; -template<typename SubClass, int type, bool addZeroTerm> +template<typename SubClass, int dataType> class LiteralFieldValue : public LiteralFieldValueB { -private: - bool getAddZeroTerm() const override{ return addZeroTerm; } public: - typedef std::unique_ptr<SubClass> UP; - - LiteralFieldValue() : LiteralFieldValueB() { } - LiteralFieldValue(const stringref& value) : LiteralFieldValueB(value) { } + explicit LiteralFieldValue(Type type) : LiteralFieldValueB(type) { } + LiteralFieldValue(Type type, const stringref& value) : LiteralFieldValueB(type, value) { } const DataType *getDataType() const override; }; -extern template class LiteralFieldValue<RawFieldValue, DataType::T_RAW, false>; -extern template class LiteralFieldValue<StringFieldValue, DataType::T_STRING, true>; +extern template class LiteralFieldValue<RawFieldValue, DataType::T_RAW>; +extern template class LiteralFieldValue<StringFieldValue, DataType::T_STRING>; } // document diff --git a/document/src/vespa/document/fieldvalue/literalfieldvalue.hpp b/document/src/vespa/document/fieldvalue/literalfieldvalue.hpp index c5b30bc5ff1..91364de29fa 100644 --- a/document/src/vespa/document/fieldvalue/literalfieldvalue.hpp +++ b/document/src/vespa/document/fieldvalue/literalfieldvalue.hpp @@ -6,17 +6,17 @@ namespace document { -template<typename SubClass, int type, bool addZeroTerm> +template<typename SubClass, int dataType> const DataType * -LiteralFieldValue<SubClass, type, addZeroTerm>::getDataType() const +LiteralFieldValue<SubClass, dataType>::getDataType() const { - switch (type) { + switch (dataType) { case DataType::T_URI: return DataType::URI; case DataType::T_STRING: return DataType::STRING; case DataType::T_RAW: return DataType::RAW; default: throw vespalib::IllegalStateException(vespalib::make_string( - "Illegal literal type id %i", type), VESPA_STRLOC); + "Illegal literal type id %i", dataType), VESPA_STRLOC); } } diff --git a/document/src/vespa/document/fieldvalue/longfieldvalue.cpp b/document/src/vespa/document/fieldvalue/longfieldvalue.cpp index f2f6cdb52b5..04f39f64beb 100644 --- a/document/src/vespa/document/fieldvalue/longfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/longfieldvalue.cpp @@ -4,6 +4,4 @@ namespace document { -IMPLEMENT_IDENTIFIABLE(LongFieldValue, NumericFieldValueBase); - } // document diff --git a/document/src/vespa/document/fieldvalue/longfieldvalue.h b/document/src/vespa/document/fieldvalue/longfieldvalue.h index 64ab4332cef..4b73ef0c2ea 100644 --- a/document/src/vespa/document/fieldvalue/longfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/longfieldvalue.h @@ -12,11 +12,11 @@ namespace document { -class LongFieldValue : public NumericFieldValue<int64_t> { +class LongFieldValue final : public NumericFieldValue<int64_t> { public: typedef int64_t Number; - LongFieldValue(Number value = 0) : NumericFieldValue<Number>(value) {} + LongFieldValue(Number value = 0) : NumericFieldValue<Number>(Type::LONG, value) {} void accept(FieldValueVisitor &visitor) override { visitor.visit(*this); } void accept(ConstFieldValueVisitor &visitor) const override { visitor.visit(*this); } @@ -25,7 +25,6 @@ public: LongFieldValue* clone() const override { return new LongFieldValue(*this); } using NumericFieldValue<Number>::operator=; - DECLARE_IDENTIFIABLE(LongFieldValue); static std::unique_ptr<LongFieldValue> make(Number value=0) { return std::make_unique<LongFieldValue>(value); } }; diff --git a/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp b/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp index 872185e7523..33ce4357f03 100644 --- a/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp @@ -25,8 +25,6 @@ namespace document { using namespace fieldvalue; -IMPLEMENT_IDENTIFIABLE_ABSTRACT(MapFieldValue, FieldValue); - namespace { const MapDataType *verifyMapType(const DataType& type) { const MapDataType *ptr(dynamic_cast<const MapDataType *>(&type)); @@ -75,14 +73,13 @@ public: } MapFieldValue::MapFieldValue(const DataType &mapType) - : FieldValue(), + : FieldValue(Type::MAP), _type(verifyMapType(mapType)), _count(0), _keys(static_cast<IArray *>(createArray(getMapType().getKeyType()).release())), _values(static_cast<IArray *>(createArray(getMapType().getValueType()).release())), _present(), - _lookupMap(), - _altered(true) + _lookupMap() { } @@ -95,8 +92,7 @@ MapFieldValue::MapFieldValue(const MapFieldValue & rhs) : _keys(rhs._keys ? rhs._keys->clone() : nullptr), _values(rhs._values ? rhs._values->clone() : nullptr), _present(rhs._present), - _lookupMap(), - _altered(rhs._altered) + _lookupMap() { } @@ -118,7 +114,6 @@ MapFieldValue::swap(MapFieldValue & rhs) { std::swap(_values, rhs._values); std::swap(_present, rhs._present); std::swap(_lookupMap, rhs._lookupMap); - std::swap(_altered, rhs._altered); } void MapFieldValue::verifyKey(const FieldValue & fv) const @@ -146,7 +141,6 @@ MapFieldValue::insertVerify(const FieldValue& key, const FieldValue& value) bool result(false); if (found != end()) { if (!(value == *found->second)) { - _altered = true; found->second->assign(value); } } else { @@ -166,8 +160,6 @@ MapFieldValue::push_back(const FieldValue& key, const FieldValue& value) if (_lookupMap) { _lookupMap->insert(_present.size() - 1); } - - _altered = true; } @@ -181,7 +173,6 @@ MapFieldValue::push_back(FieldValue::UP key, FieldValue::UP value) if (_lookupMap) { _lookupMap->insert(_present.size() - 1); } - _altered = true; } bool @@ -255,7 +246,6 @@ MapFieldValue::erase(const FieldValue& key) _count--; _present[found.offset()] = false; _lookupMap->erase(found.offset()); - _altered = true; } return result; } @@ -331,13 +321,6 @@ MapFieldValue::printXml(XmlOutputStream& xos) const } } -bool -MapFieldValue::hasChanged() const -{ - // Keys are not allowed to change in a map, so the keys should not be - // referred to externally, and should thus not need to be checked. - return _altered; -} const DataType * MapFieldValue::getDataType() const { return _type; @@ -369,7 +352,7 @@ MapFieldValue::buildLookupMap() const { MapFieldValue::const_iterator MapFieldValue::find(const FieldValue& key) const { - if ((size() > 0) && (key.getClass().id() == (*_keys)[0].getClass().id())) { + if ((size() > 0) && (key.type() == (*_keys)[0].type())) { ssize_t index = findIndex(key); if (index >= 0) { return const_iterator(*this, index); @@ -381,7 +364,7 @@ MapFieldValue::find(const FieldValue& key) const MapFieldValue::iterator MapFieldValue::find(const FieldValue& key) { - if ((size() > 0) && (key.getClass().id() == (*_keys)[0].getClass().id())) { + if ((size() > 0) && (key.type() == (*_keys)[0].type())) { ssize_t index = findIndex(key); if (index >= 0) { return iterator(*this, index); @@ -393,7 +376,7 @@ MapFieldValue::find(const FieldValue& key) ssize_t MapFieldValue::findIndex(const FieldValue& key) const { - if ((size() > 0) && (key.getClass().id() == (*_keys)[0].getClass().id())) { + if ((size() > 0) && (key.type() == (*_keys)[0].type())) { ensureLookupMap(); auto found = _lookupMap->find(key); if (found != _lookupMap->end()) { @@ -428,7 +411,7 @@ MapFieldValue::iterateNestedImpl(PathRange nested, IteratorHandler::CollectionScope autoScope(handler, complexFieldValue); std::vector<const FieldValue*> keysToRemove; bool wasModified = false; - const bool isWSet(complexFieldValue.inherits(WeightedSetFieldValue::classId)); + const bool isWSet(complexFieldValue.isA(FieldValue::Type::WSET)); uint32_t index(0); if ( ! nested.atEnd() ) { diff --git a/document/src/vespa/document/fieldvalue/mapfieldvalue.h b/document/src/vespa/document/fieldvalue/mapfieldvalue.h index 5e8de6f3ed8..551543684f0 100644 --- a/document/src/vespa/document/fieldvalue/mapfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/mapfieldvalue.h @@ -18,7 +18,7 @@ namespace document { namespace mapfieldvalue { class HashMap; } -class MapFieldValue : public FieldValue +class MapFieldValue final : public FieldValue { public: using IArray=vespalib::IArrayT<FieldValue>; @@ -134,7 +134,6 @@ public: MapFieldValue* clone() const override { return new MapFieldValue(*this); } int compare(const FieldValue&) const override; void print(std::ostream& out, bool verbose, const std::string& indent) const override; - bool hasChanged() const override; const DataType *getDataType() const override; void printXml(XmlOutputStream& out) const override; @@ -162,8 +161,6 @@ public: } FieldValue::UP createValue() const; - - DECLARE_IDENTIFIABLE_ABSTRACT(MapFieldValue); }; } // namespace document diff --git a/document/src/vespa/document/fieldvalue/numericfieldvalue.cpp b/document/src/vespa/document/fieldvalue/numericfieldvalue.cpp index 7d02054f668..6247e815d73 100644 --- a/document/src/vespa/document/fieldvalue/numericfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/numericfieldvalue.cpp @@ -6,8 +6,6 @@ namespace document { -IMPLEMENT_IDENTIFIABLE_ABSTRACT(NumericFieldValueBase, FieldValue); - void NumericFieldValueBase::printXml(XmlOutputStream& out) const { diff --git a/document/src/vespa/document/fieldvalue/numericfieldvalue.h b/document/src/vespa/document/fieldvalue/numericfieldvalue.h index 28981fc5286..a19456f0e4a 100644 --- a/document/src/vespa/document/fieldvalue/numericfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/numericfieldvalue.h @@ -18,21 +18,19 @@ namespace document { class NumericFieldValueBase : public FieldValue { public: - DECLARE_IDENTIFIABLE_ABSTRACT(NumericFieldValueBase); void printXml(XmlOutputStream& out) const override; +protected: + NumericFieldValueBase(Type type) : FieldValue(type) {} }; template<typename Number> class NumericFieldValue : public NumericFieldValueBase { protected: + explicit NumericFieldValue(Type type, Number value=0) : NumericFieldValueBase(type), _value(value) { } Number _value; - bool _altered; - public: typedef Number value_type; - explicit NumericFieldValue(Number value=0) : NumericFieldValueBase(), _value(value), _altered(false) { } - value_type getValue() const { return _value; } void setValue(Number newValue) { _value = newValue; } @@ -51,7 +49,6 @@ public: vespalib::string getAsString() const override; void print(std::ostream& out, bool verbose, const std::string& indent) const override; - bool hasChanged() const override final { return _altered; } }; extern template class NumericFieldValue<float>; diff --git a/document/src/vespa/document/fieldvalue/numericfieldvalue.hpp b/document/src/vespa/document/fieldvalue/numericfieldvalue.hpp index f1bbce5450d..0c214a97aec 100644 --- a/document/src/vespa/document/fieldvalue/numericfieldvalue.hpp +++ b/document/src/vespa/document/fieldvalue/numericfieldvalue.hpp @@ -17,22 +17,21 @@ template<typename Number> FieldValue& NumericFieldValue<Number>::assign(const FieldValue& value) { - if (value.getClass().id() == IDENTIFIABLE_CLASSID(ByteFieldValue)) { + if (value.isA(FieldValue::Type::BYTE)) { _value = static_cast<Number>(value.getAsByte()); - } else if (value.getClass().id() == IDENTIFIABLE_CLASSID(ShortFieldValue)) { + } else if (value.isA(FieldValue::Type::SHORT)) { _value = static_cast<Number>(value.getAsInt()); - } else if (value.getClass().id() == IDENTIFIABLE_CLASSID(IntFieldValue)) { + } else if (value.isA(FieldValue::Type::INT)) { _value = static_cast<Number>(value.getAsInt()); - } else if (value.getClass().id() == IDENTIFIABLE_CLASSID(LongFieldValue)) { + } else if (value.isA(FieldValue::Type::LONG)) { _value = static_cast<Number>(value.getAsLong()); - } else if (value.getClass().id() == IDENTIFIABLE_CLASSID(FloatFieldValue)) { + } else if (value.isA(FieldValue::Type::FLOAT)) { _value = static_cast<Number>(value.getAsFloat()); - } else if (value.getClass().id() == IDENTIFIABLE_CLASSID(DoubleFieldValue)) { + } else if (value.isA(FieldValue::Type::DOUBLE)) { _value = static_cast<Number>(value.getAsDouble()); } else { return FieldValue::assign(value); } - _altered = true; return *this; } @@ -91,7 +90,6 @@ NumericFieldValue<Number>::operator=(vespalib::stringref value) // Allow numbers to be specified in range max signed to max // unsigned. These become negative numbers. _value = static_cast<Number>(val); - _altered = true; return *this; } } @@ -118,7 +116,6 @@ NumericFieldValue<Number>::operator=(vespalib::stringref value) } } } - _altered = true; return *this; } diff --git a/document/src/vespa/document/fieldvalue/predicatefieldvalue.cpp b/document/src/vespa/document/fieldvalue/predicatefieldvalue.cpp index 3a62eb5060c..b474db2ab6e 100644 --- a/document/src/vespa/document/fieldvalue/predicatefieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/predicatefieldvalue.cpp @@ -14,22 +14,19 @@ using namespace vespalib::xml; namespace document { -IMPLEMENT_IDENTIFIABLE(PredicateFieldValue, FieldValue); - PredicateFieldValue::PredicateFieldValue() - : _slime(std::make_unique<Slime>()), _altered(false) { -} + : FieldValue(Type::PREDICATE), + _slime(std::make_unique<Slime>()) +{ } PredicateFieldValue::PredicateFieldValue(vespalib::Slime::UP s) - : FieldValue(), - _slime(std::move(s)), - _altered(false) + : FieldValue(Type::PREDICATE), + _slime(std::move(s)) { } PredicateFieldValue::PredicateFieldValue(const PredicateFieldValue &rhs) : FieldValue(rhs), - _slime(new Slime), - _altered(rhs._altered) + _slime(new Slime) { inject(rhs._slime->get(), SlimeInserter(*_slime)); } @@ -38,11 +35,10 @@ PredicateFieldValue::~PredicateFieldValue() = default; FieldValue & PredicateFieldValue::assign(const FieldValue &rhs) { - if (rhs.inherits(PredicateFieldValue::classId)) { + if (rhs.isA(Type::PREDICATE)) { operator=(static_cast<const PredicateFieldValue &>(rhs)); } else { _slime.reset(); - _altered = true; } return *this; } @@ -52,7 +48,6 @@ PredicateFieldValue::operator=(const PredicateFieldValue &rhs) { _slime = std::make_unique<Slime>(); inject(rhs._slime->get(), SlimeInserter(*_slime)); - _altered = true; return *this; } @@ -79,11 +74,6 @@ PredicateFieldValue::getDataType() const { return DataType::PREDICATE; } -bool -PredicateFieldValue::hasChanged() const { - return _altered; -} - FieldValue * PredicateFieldValue::clone() const { return new PredicateFieldValue(*this); diff --git a/document/src/vespa/document/fieldvalue/predicatefieldvalue.h b/document/src/vespa/document/fieldvalue/predicatefieldvalue.h index 5f7db35f953..c99a82a59e2 100644 --- a/document/src/vespa/document/fieldvalue/predicatefieldvalue.h +++ b/document/src/vespa/document/fieldvalue/predicatefieldvalue.h @@ -9,9 +9,8 @@ namespace vespalib { } namespace document { -class PredicateFieldValue : public FieldValue { +class PredicateFieldValue final : public FieldValue { std::unique_ptr<vespalib::Slime> _slime; - bool _altered; PredicateFieldValue & operator=(const PredicateFieldValue &rhs); public: @@ -33,13 +32,10 @@ public: void print(std::ostream &out, bool verbose, const std::string &indent) const override; const DataType *getDataType() const override; - bool hasChanged() const override; const vespalib::Slime &getSlime() const { return *_slime; } FieldValue &assign(const FieldValue &rhs) override; - - DECLARE_IDENTIFIABLE(PredicateFieldValue); }; } diff --git a/document/src/vespa/document/fieldvalue/rawfieldvalue.cpp b/document/src/vespa/document/fieldvalue/rawfieldvalue.cpp index 95f066b86ed..ab17a879dfa 100644 --- a/document/src/vespa/document/fieldvalue/rawfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/rawfieldvalue.cpp @@ -9,8 +9,6 @@ using namespace vespalib::xml; namespace document { -IMPLEMENT_IDENTIFIABLE(RawFieldValue, LiteralFieldValueB); - void RawFieldValue::printXml(XmlOutputStream& out) const { diff --git a/document/src/vespa/document/fieldvalue/rawfieldvalue.h b/document/src/vespa/document/fieldvalue/rawfieldvalue.h index 98110816a9d..b946ecd0038 100644 --- a/document/src/vespa/document/fieldvalue/rawfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/rawfieldvalue.h @@ -12,20 +12,19 @@ namespace document { -class RawFieldValue - : public LiteralFieldValue<RawFieldValue, DataType::T_RAW, false> +class RawFieldValue final : public LiteralFieldValue<RawFieldValue, DataType::T_RAW> { public: - typedef LiteralFieldValue<RawFieldValue, DataType::T_RAW, false> Parent; + typedef LiteralFieldValue<RawFieldValue, DataType::T_RAW> Parent; RawFieldValue() - : Parent() { } + : Parent(Type::RAW) { } RawFieldValue(const string& value) - : Parent(value) {} + : Parent(Type::RAW, value) {} RawFieldValue(const char* rawVal, int len) - : Parent(string(rawVal, len)) + : Parent(Type::RAW, string(rawVal, len)) { } @@ -37,8 +36,6 @@ public: void print(std::ostream& out, bool verbose, const std::string& indent) const override; RawFieldValue& operator=(const string& value) { setValue(value); return *this; } - - DECLARE_IDENTIFIABLE(RawFieldValue); }; } // document diff --git a/document/src/vespa/document/fieldvalue/referencefieldvalue.cpp b/document/src/vespa/document/fieldvalue/referencefieldvalue.cpp index 328e5b67151..cade633fb00 100644 --- a/document/src/vespa/document/fieldvalue/referencefieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/referencefieldvalue.cpp @@ -11,28 +11,24 @@ using vespalib::make_string; namespace document { -IMPLEMENT_IDENTIFIABLE(ReferenceFieldValue, FieldValue); - ReferenceFieldValue::ReferenceFieldValue() - : _dataType(nullptr), - _documentId(), - _altered(true) + : FieldValue(Type::REFERENCE), + _dataType(nullptr), + _documentId() { } ReferenceFieldValue::ReferenceFieldValue(const ReferenceDataType& dataType) - : _dataType(&dataType), - _documentId(), - _altered(true) + : FieldValue(Type::REFERENCE), + _dataType(&dataType), + _documentId() { } -ReferenceFieldValue::ReferenceFieldValue( - const ReferenceDataType& dataType, - const DocumentId& documentId) - : _dataType(&dataType), - _documentId(documentId), - _altered(true) +ReferenceFieldValue::ReferenceFieldValue(const ReferenceDataType& dataType, const DocumentId& documentId) + : FieldValue(Type::REFERENCE), + _dataType(&dataType), + _documentId(documentId) { requireIdOfMatchingType(_documentId, _dataType->getTargetType()); } @@ -67,7 +63,6 @@ FieldValue& ReferenceFieldValue::assign(const FieldValue& rhs) { } _documentId = refValueRhs->_documentId; _dataType = refValueRhs->_dataType; - _altered = true; return *this; } @@ -77,7 +72,6 @@ void ReferenceFieldValue::setDeserializedDocumentId(const DocumentId& id) { _documentId = id; // Pre-cache GID to ensure it's not attempted lazily initialized later in a racing manner. (void) _documentId.getGlobalId(); - _altered = false; } ReferenceFieldValue* ReferenceFieldValue::clone() const { @@ -109,10 +103,6 @@ void ReferenceFieldValue::print(std::ostream& os, bool verbose, const std::strin os << indent << "ReferenceFieldValue(" << *_dataType << ", DocumentId(" << _documentId << "))"; } -bool ReferenceFieldValue::hasChanged() const { - return _altered; -} - void ReferenceFieldValue::accept(FieldValueVisitor& visitor) { visitor.visit(*this); } diff --git a/document/src/vespa/document/fieldvalue/referencefieldvalue.h b/document/src/vespa/document/fieldvalue/referencefieldvalue.h index d8160353b5f..c8adb49102a 100644 --- a/document/src/vespa/document/fieldvalue/referencefieldvalue.h +++ b/document/src/vespa/document/fieldvalue/referencefieldvalue.h @@ -22,11 +22,10 @@ namespace document { * document type "foo" inheriting "bar", you cannot have a reference<bar> field * containing a document ID for a "foo" document. */ -class ReferenceFieldValue : public FieldValue { +class ReferenceFieldValue final : public FieldValue { const ReferenceDataType* _dataType; // TODO wrap in std::optional once available. DocumentId _documentId; - bool _altered; public: // Empty constructor required for Identifiable. ReferenceFieldValue(); @@ -53,9 +52,6 @@ public: // Should only be called by deserializer code, as it will clear hasChanged. // `id` must be a valid document ID and cannot be empty. void setDeserializedDocumentId(const DocumentId& id); - void clearChanged() { - _altered = false; - } const DataType* getDataType() const override { return _dataType; } FieldValue& assign(const FieldValue&) override; @@ -63,16 +59,12 @@ public: int compare(const FieldValue&) const override; void printXml(XmlOutputStream&) const override { /* Not implemented */ } void print(std::ostream&, bool, const std::string&) const override; - bool hasChanged() const override; void accept(FieldValueVisitor&) override; void accept(ConstFieldValueVisitor&) const override; - - DECLARE_IDENTIFIABLE(ReferenceFieldValue); private: // Throws vespalib::IllegalArgumentException if doc type of `id` does not // match the name of `type`. - static void requireIdOfMatchingType( - const DocumentId& id, const DocumentType& type); + static void requireIdOfMatchingType(const DocumentId& id, const DocumentType& type); }; } // document diff --git a/document/src/vespa/document/fieldvalue/shortfieldvalue.cpp b/document/src/vespa/document/fieldvalue/shortfieldvalue.cpp index 9f0334a12ae..02fa8fb30a2 100644 --- a/document/src/vespa/document/fieldvalue/shortfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/shortfieldvalue.cpp @@ -5,6 +5,4 @@ namespace document { -IMPLEMENT_IDENTIFIABLE(ShortFieldValue, NumericFieldValueBase); - } // document diff --git a/document/src/vespa/document/fieldvalue/shortfieldvalue.h b/document/src/vespa/document/fieldvalue/shortfieldvalue.h index fa61c37c4eb..e135f2a4f54 100644 --- a/document/src/vespa/document/fieldvalue/shortfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/shortfieldvalue.h @@ -12,13 +12,13 @@ namespace document { -class ShortFieldValue : public NumericFieldValue<int16_t> { +class ShortFieldValue final : public NumericFieldValue<int16_t> { public: typedef std::unique_ptr<ShortFieldValue> UP; typedef int16_t Number; ShortFieldValue(Number value = 0) - : NumericFieldValue<Number>(value) {} + : NumericFieldValue<Number>(Type::SHORT, value) {} void accept(FieldValueVisitor &visitor) override { visitor.visit(*this); } void accept(ConstFieldValueVisitor &visitor) const override { visitor.visit(*this); } @@ -27,7 +27,6 @@ public: ShortFieldValue* clone() const override { return new ShortFieldValue(*this); } using NumericFieldValue<Number>::operator=; - DECLARE_IDENTIFIABLE(ShortFieldValue); static std::unique_ptr<ShortFieldValue> make(int16_t value = 0) { return std::make_unique<ShortFieldValue>(value); } }; diff --git a/document/src/vespa/document/fieldvalue/stringfieldvalue.cpp b/document/src/vespa/document/fieldvalue/stringfieldvalue.cpp index 0a46a11bddf..47e96b4f4e4 100644 --- a/document/src/vespa/document/fieldvalue/stringfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/stringfieldvalue.cpp @@ -19,17 +19,16 @@ using vespalib::stringref; namespace document { -IMPLEMENT_IDENTIFIABLE(StringFieldValue, LiteralFieldValueB); - -StringFieldValue::StringFieldValue(const StringFieldValue & rhs) : - Parent(rhs), - _annotationData(rhs.copyAnnotationData()) +StringFieldValue::StringFieldValue(const StringFieldValue & rhs) + : Parent(rhs), + _annotationData(rhs.copyAnnotationData()) { } -StringFieldValue::~StringFieldValue() {} +StringFieldValue::~StringFieldValue() = default; -StringFieldValue & StringFieldValue::operator=(const StringFieldValue & rhs) +StringFieldValue & +StringFieldValue::operator=(const StringFieldValue & rhs) { if (&rhs != this) { Parent::operator=(rhs); @@ -38,8 +37,9 @@ StringFieldValue & StringFieldValue::operator=(const StringFieldValue & rhs) return *this; } -int StringFieldValue::compare(const FieldValue& other) const { - if (other.inherits(StringFieldValue::classId)) { +int +StringFieldValue::compare(const FieldValue& other) const { + if (other.isA(Type::STRING)) { const StringFieldValue &other_s(static_cast<const StringFieldValue &>(other)); return _value.compare(other_s._value); } else { @@ -47,7 +47,8 @@ int StringFieldValue::compare(const FieldValue& other) const { } } -void StringFieldValue::print(std::ostream& out, bool verbose, const std::string& indent) const { +void +StringFieldValue::print(std::ostream& out, bool verbose, const std::string& indent) const { if ( ! hasSpanTrees()) { Parent::print(out, verbose, indent); } else { @@ -88,7 +89,8 @@ StringFieldValue::doClearSpanTrees() { _annotationData.reset(); } -const SpanTree * StringFieldValue::findTree(const SpanTrees & trees, stringref name) +const SpanTree * +StringFieldValue::findTree(const SpanTrees & trees, stringref name) { for(const auto & tree : trees) { if (tree->getName() == name) { @@ -98,16 +100,18 @@ const SpanTree * StringFieldValue::findTree(const SpanTrees & trees, stringref n return nullptr; } -StringFieldValue &StringFieldValue::operator=(stringref value) +StringFieldValue & +StringFieldValue::operator=(stringref value) { setValue(value); _annotationData.reset(); return *this; } -FieldValue & StringFieldValue::assign(const FieldValue & rhs) +FieldValue & +StringFieldValue::assign(const FieldValue & rhs) { - if (rhs.inherits(StringFieldValue::classId)) { + if (rhs.isA(Type::STRING)) { *this = static_cast<const StringFieldValue &>(rhs); } else { *this = rhs.getAsString().operator stringref(); diff --git a/document/src/vespa/document/fieldvalue/stringfieldvalue.h b/document/src/vespa/document/fieldvalue/stringfieldvalue.h index 07e9e578692..95cd9c6190c 100644 --- a/document/src/vespa/document/fieldvalue/stringfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/stringfieldvalue.h @@ -17,14 +17,14 @@ namespace document { class FixedTypeRepo; class DocumentTypeRepo; -class StringFieldValue : public LiteralFieldValue<StringFieldValue, DataType::T_STRING, true> { +class StringFieldValue final : public LiteralFieldValue<StringFieldValue, DataType::T_STRING> { public: - typedef LiteralFieldValue<StringFieldValue, DataType::T_STRING, true> Parent; + typedef LiteralFieldValue<StringFieldValue, DataType::T_STRING> Parent; typedef std::vector<SpanTree::UP> SpanTrees; - StringFieldValue() : Parent(), _annotationData() { } + StringFieldValue() : Parent(Type::STRING), _annotationData() { } StringFieldValue(const vespalib::stringref &value) - : Parent(value), _annotationData() { } + : Parent(Type::STRING, value), _annotationData() { } StringFieldValue(const StringFieldValue &rhs); @@ -55,7 +55,6 @@ public: } using LiteralFieldValueB::operator=; - DECLARE_IDENTIFIABLE(StringFieldValue); static std::unique_ptr<StringFieldValue> make(vespalib::stringref value) { return std::make_unique<StringFieldValue>(value); } static std::unique_ptr<StringFieldValue> make() { return StringFieldValue::make(""); } private: diff --git a/document/src/vespa/document/fieldvalue/structfieldvalue.cpp b/document/src/vespa/document/fieldvalue/structfieldvalue.cpp index fbe6dadb320..529e608533e 100644 --- a/document/src/vespa/document/fieldvalue/structfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/structfieldvalue.cpp @@ -27,10 +27,8 @@ using namespace vespalib::xml; namespace document { -IMPLEMENT_IDENTIFIABLE_ABSTRACT(StructFieldValue, StructuredFieldValue); - StructFieldValue::StructFieldValue(const DataType &type) - : StructuredFieldValue(type), + : StructuredFieldValue(Type::STRUCT, type), _fields(), _repo(nullptr), _doc_type(nullptr), diff --git a/document/src/vespa/document/fieldvalue/structfieldvalue.h b/document/src/vespa/document/fieldvalue/structfieldvalue.h index 24e143ddc27..564c48273e6 100644 --- a/document/src/vespa/document/fieldvalue/structfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/structfieldvalue.h @@ -22,7 +22,7 @@ class FixedTypeRepo; class FieldSet; class StructDataType; -class StructFieldValue : public StructuredFieldValue +class StructFieldValue final : public StructuredFieldValue { private: SerializableArray _fields; @@ -76,7 +76,12 @@ public: bool empty() const override; - bool hasChanged() const override { return _hasChanged; } + /** + * Returns true if this object have been altered since last + * serialization/deserialization. If hasChanged() is false, then cached + * information from last serialization effort is still valid. + */ + bool hasChanged() const { return _hasChanged; } uint32_t calculateChecksum() const; @@ -85,9 +90,6 @@ public: * has no content. This clears content and sets changed to false. */ void reset(); - - DECLARE_IDENTIFIABLE_ABSTRACT(StructFieldValue); - private: void setFieldValue(const Field&, FieldValue::UP value) override; FieldValue::UP getFieldValue(const Field&) const override; diff --git a/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp b/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp index 53f75cb2e73..53a5fa14fee 100644 --- a/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp @@ -16,8 +16,6 @@ namespace document { using namespace fieldvalue; -IMPLEMENT_IDENTIFIABLE_ABSTRACT(StructuredFieldValue, FieldValue); - StructuredFieldValue::Iterator::Iterator() : _iterator(), _field(nullptr) diff --git a/document/src/vespa/document/fieldvalue/structuredfieldvalue.h b/document/src/vespa/document/fieldvalue/structuredfieldvalue.h index 9d79b6279a4..fdc4ecf7765 100644 --- a/document/src/vespa/document/fieldvalue/structuredfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/structuredfieldvalue.h @@ -44,7 +44,7 @@ class StructuredFieldValue : public FieldValue virtual StructuredCache * getCache() const { return nullptr; } protected: - StructuredFieldValue(const DataType &type) : FieldValue(), _type(&type) {} + StructuredFieldValue(Type type, const DataType &dataType) : FieldValue(type), _type(&dataType) {} /** Called from Document when deserializing alters type. */ virtual void setType(const DataType& type) { _type = &type; } @@ -106,8 +106,6 @@ protected: fieldvalue::ModificationStatus onIterateNested(PathRange nested, fieldvalue::IteratorHandler & handler) const override; public: - DECLARE_IDENTIFIABLE_ABSTRACT(StructuredFieldValue); - StructuredFieldValue* clone() const override = 0; const DataType *getDataType() const override { return _type; } diff --git a/document/src/vespa/document/fieldvalue/structuredfieldvalue.hpp b/document/src/vespa/document/fieldvalue/structuredfieldvalue.hpp index 4b347d7cc07..c142fd9b6eb 100644 --- a/document/src/vespa/document/fieldvalue/structuredfieldvalue.hpp +++ b/document/src/vespa/document/fieldvalue/structuredfieldvalue.hpp @@ -12,7 +12,7 @@ template <typename T> std::unique_ptr<T> StructuredFieldValue::getAs(const Field &field) const { FieldValue::UP val = getValue(field); - T *t = Identifiable::cast<T *>(val.get()); + T *t = dynamic_cast<T *>(val.get()); if (val.get() && !t) { throw vespalib::IllegalStateException("Field " + field.toString() + " has unexpected type.", VESPA_STRLOC); } diff --git a/document/src/vespa/document/fieldvalue/tensorfieldvalue.cpp b/document/src/vespa/document/fieldvalue/tensorfieldvalue.cpp index 42f4080d6b6..d9a56f9fa56 100644 --- a/document/src/vespa/document/fieldvalue/tensorfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/tensorfieldvalue.cpp @@ -36,18 +36,16 @@ TensorFieldValue::TensorFieldValue() } TensorFieldValue::TensorFieldValue(const TensorDataType &dataType) - : FieldValue(), + : FieldValue(Type::TENSOR), _dataType(dataType), - _tensor(), - _altered(true) + _tensor() { } TensorFieldValue::TensorFieldValue(const TensorFieldValue &rhs) - : FieldValue(), + : FieldValue(Type::TENSOR), _dataType(rhs._dataType), - _tensor(), - _altered(true) + _tensor() { if (rhs._tensor) { _tensor = FastValueBuilderFactory::get().copy(*rhs._tensor); @@ -56,10 +54,9 @@ TensorFieldValue::TensorFieldValue(const TensorFieldValue &rhs) TensorFieldValue::TensorFieldValue(TensorFieldValue &&rhs) - : FieldValue(), + : FieldValue(Type::TENSOR), _dataType(rhs._dataType), - _tensor(), - _altered(true) + _tensor() { _tensor = std::move(rhs._tensor); } @@ -81,7 +78,6 @@ TensorFieldValue::operator=(const TensorFieldValue &rhs) } else { _tensor.reset(); } - _altered = true; } else { throw WrongTensorTypeException(makeWrongTensorTypeMsg(_dataType.getTensorType(), rhs._tensor->type()), VESPA_STRLOC); } @@ -95,7 +91,6 @@ TensorFieldValue::operator=(std::unique_ptr<vespalib::eval::Value> rhs) { if (!rhs || _dataType.isAssignableType(rhs->type())) { _tensor = std::move(rhs); - _altered = true; } else { throw WrongTensorTypeException(makeWrongTensorTypeMsg(_dataType.getTensorType(), rhs->type()), VESPA_STRLOC); } @@ -133,14 +128,6 @@ TensorFieldValue::getDataType() const return &_dataType; } - -bool -TensorFieldValue::hasChanged() const -{ - return _altered; -} - - TensorFieldValue* TensorFieldValue::clone() const { @@ -173,9 +160,8 @@ TensorFieldValue::printXml(XmlOutputStream& out) const FieldValue & TensorFieldValue::assign(const FieldValue &value) { - const TensorFieldValue *rhs = - Identifiable::cast<const TensorFieldValue *>(&value); - if (rhs != nullptr) { + if (value.isA(Type::TENSOR)) { + const auto * rhs = static_cast<const TensorFieldValue *>(&value); *this = *rhs; } else { return FieldValue::assign(value); @@ -189,7 +175,6 @@ TensorFieldValue::assignDeserialized(std::unique_ptr<vespalib::eval::Value> rhs) { if (!rhs || _dataType.isAssignableType(rhs->type())) { _tensor = std::move(rhs); - _altered = false; // Serialized form already exists } else { throw WrongTensorTypeException(makeWrongTensorTypeMsg(_dataType.getTensorType(), rhs->type()), VESPA_STRLOC); } @@ -232,6 +217,4 @@ TensorFieldValue::compare(const FieldValue &other) const return lhs_spec.compare(rhs_spec); } -IMPLEMENT_IDENTIFIABLE(TensorFieldValue, FieldValue); - } // document diff --git a/document/src/vespa/document/fieldvalue/tensorfieldvalue.h b/document/src/vespa/document/fieldvalue/tensorfieldvalue.h index 6cb2ff08c2e..52b27346ff8 100644 --- a/document/src/vespa/document/fieldvalue/tensorfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/tensorfieldvalue.h @@ -13,39 +13,34 @@ class TensorDataType; /** * Field value representing a tensor. */ -class TensorFieldValue : public FieldValue { +class TensorFieldValue final : public FieldValue { private: const TensorDataType &_dataType; std::unique_ptr<vespalib::eval::Value> _tensor; - bool _altered; public: TensorFieldValue(); explicit TensorFieldValue(const TensorDataType &dataType); TensorFieldValue(const TensorFieldValue &rhs); TensorFieldValue(TensorFieldValue &&rhs); - ~TensorFieldValue(); + ~TensorFieldValue() override; TensorFieldValue &operator=(const TensorFieldValue &rhs); TensorFieldValue &operator=(std::unique_ptr<vespalib::eval::Value> rhs); void make_empty_if_not_existing(); - virtual void accept(FieldValueVisitor &visitor) override; - virtual void accept(ConstFieldValueVisitor &visitor) const override; - virtual const DataType *getDataType() const override; - virtual bool hasChanged() const override; - virtual TensorFieldValue* clone() const override; - virtual void print(std::ostream& out, bool verbose, - const std::string& indent) const override; - virtual void printXml(XmlOutputStream& out) const override; - virtual FieldValue &assign(const FieldValue &value) override; + void accept(FieldValueVisitor &visitor) override; + void accept(ConstFieldValueVisitor &visitor) const override; + const DataType *getDataType() const override; + TensorFieldValue* clone() const override; + void print(std::ostream& out, bool verbose, const std::string& indent) const override; + void printXml(XmlOutputStream& out) const override; + FieldValue &assign(const FieldValue &value) override; const vespalib::eval::Value *getAsTensorPtr() const { return _tensor.get(); } void assignDeserialized(std::unique_ptr<vespalib::eval::Value> rhs); - virtual int compare(const FieldValue& other) const override; - - DECLARE_IDENTIFIABLE(TensorFieldValue); + int compare(const FieldValue& other) const override; }; } // document diff --git a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp index 2a3726095df..fd26deab15a 100644 --- a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp @@ -18,8 +18,6 @@ namespace document { using namespace fieldvalue; -IMPLEMENT_IDENTIFIABLE_ABSTRACT(WeightedSetFieldValue, CollectionFieldValue); - namespace { const DataType &getKeyType(const DataType &type) { const WeightedSetDataType *wtype = dynamic_cast<const WeightedSetDataType *>(&type); @@ -32,10 +30,9 @@ const DataType &getKeyType(const DataType &type) { } // namespace WeightedSetFieldValue::WeightedSetFieldValue(const DataType &type) - : CollectionFieldValue(type), + : CollectionFieldValue(Type::WSET, type), _map_type(std::make_shared<MapDataType>(getKeyType(type), *DataType::INT)), - _map(*_map_type), - _altered(true) + _map(*_map_type) { } WeightedSetFieldValue::WeightedSetFieldValue(const WeightedSetFieldValue &) = default; @@ -54,7 +51,6 @@ WeightedSetFieldValue::add(const FieldValue& key, int weight) { verifyKey(key); const WeightedSetDataType & wdt(static_cast<const WeightedSetDataType&>(*_type)); - _altered = true; if (wdt.removeIfZero() && (weight == 0)) { _map.erase(key); return false; @@ -66,14 +62,12 @@ bool WeightedSetFieldValue::addIgnoreZeroWeight(const FieldValue& key, int32_t weight) { verifyKey(key); - _altered = true; return _map.insert(FieldValue::UP(key.clone()), IntFieldValue::make(weight)); } void WeightedSetFieldValue::push_back(FieldValue::UP key, int weight) { - _altered = true; _map.push_back(std::move(key), IntFieldValue::make(weight)); } @@ -103,7 +97,6 @@ WeightedSetFieldValue::increment(const FieldValue& key, int val) _map.erase(key); } } - _altered = true; } int32_t @@ -125,7 +118,6 @@ bool WeightedSetFieldValue::removeValue(const FieldValue& key) { bool result = _map.erase(key); - _altered |= result; return result; } @@ -179,14 +171,6 @@ WeightedSetFieldValue::print(std::ostream& out, bool verbose, const std::string& out << ")"; } -bool -WeightedSetFieldValue::hasChanged() const -{ - // Keys are not allowed to change in a map, so the keys should not be - // referred to externally, and should thus not need to be checked. - return _altered; -} - WeightedSetFieldValue::const_iterator WeightedSetFieldValue::find(const FieldValue& key) const { diff --git a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h index d58819607b4..b2183efef42 100644 --- a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h @@ -14,7 +14,7 @@ namespace document { -class WeightedSetFieldValue : public CollectionFieldValue +class WeightedSetFieldValue final : public CollectionFieldValue { public: struct FieldValuePtrOrder { @@ -26,7 +26,6 @@ public: private: std::shared_ptr<const MapDataType> _map_type; WeightedFieldValueMap _map; - bool _altered; void verifyKey(const FieldValue & key); bool addValue(const FieldValue& fval) override { return add(fval, 1); } @@ -46,7 +45,7 @@ public: WeightedSetFieldValue & operator = (const WeightedSetFieldValue &); WeightedSetFieldValue(WeightedSetFieldValue &&) = default; WeightedSetFieldValue & operator = (WeightedSetFieldValue &&) = default; - ~WeightedSetFieldValue(); + ~WeightedSetFieldValue() override; void accept(FieldValueVisitor &visitor) override { visitor.visit(*this); } void accept(ConstFieldValueVisitor &visitor) const override { visitor.visit(*this); } @@ -78,7 +77,6 @@ public: int compare(const FieldValue&) const override; void printXml(XmlOutputStream& out) const override; void print(std::ostream& out, bool verbose, const std::string& indent) const override; - bool hasChanged() const override; // Implements iterating through internal content. typedef WeightedFieldValueMap::const_iterator const_iterator; @@ -92,8 +90,6 @@ public: const_iterator find(const FieldValue& fv) const; iterator find(const FieldValue& fv); - - DECLARE_IDENTIFIABLE_ABSTRACT(WeightedSetFieldValue); }; } // document diff --git a/document/src/vespa/document/select/valuenodes.cpp b/document/src/vespa/document/select/valuenodes.cpp index 52e6b2e4223..f34b2e83b08 100644 --- a/document/src/vespa/document/select/valuenodes.cpp +++ b/document/src/vespa/document/select/valuenodes.cpp @@ -11,7 +11,6 @@ #include <vespa/vespalib/util/md5.h> #include <vespa/document/util/stringutil.h> #include <vespa/vespalib/text/lowercase.h> -#include <regex> #include <iomanip> #include <sys/time.h> @@ -272,43 +271,43 @@ IteratorHandler::onPrimitive(uint32_t fid, const Content& fv) { std::unique_ptr<Value> IteratorHandler::getInternalValue(const FieldValue& fval) const { - switch(fval.getClass().id()) { - case document::BoolFieldValue::classId: + switch(fval.type()) { + case FieldValue::Type::BOOL: { const auto& val(dynamic_cast<const BoolFieldValue&>(fval)); return std::make_unique<IntegerValue>(val.getAsInt(), false); } - case document::IntFieldValue::classId: + case FieldValue::Type::INT: { const auto& val(dynamic_cast<const IntFieldValue&>(fval)); return std::make_unique<IntegerValue>(val.getAsInt(), false); } - case document::ByteFieldValue::classId: + case FieldValue::Type::BYTE: { const auto& val(dynamic_cast<const ByteFieldValue&>(fval)); return std::make_unique<IntegerValue>(val.getAsByte(), false); } - case LongFieldValue::classId: + case FieldValue::Type::LONG: { const auto& val(dynamic_cast<const LongFieldValue&>(fval)); return std::make_unique<IntegerValue>(val.getAsLong(), false); } - case FloatFieldValue::classId: + case FieldValue::Type::FLOAT: { const auto& val(dynamic_cast<const FloatFieldValue&>(fval)); return std::make_unique<FloatValue>(val.getAsFloat()); } - case DoubleFieldValue::classId: + case FieldValue::Type::DOUBLE: { const auto& val(dynamic_cast<const DoubleFieldValue&>(fval)); return std::make_unique<FloatValue>(val.getAsDouble()); } - case StringFieldValue::classId: + case FieldValue::Type::STRING: { const auto& val(dynamic_cast<const StringFieldValue&>(fval)); return std::make_unique<StringValue>(val.getAsString()); } - case ReferenceFieldValue::classId: + case FieldValue::Type::REFERENCE: { const auto& val(dynamic_cast<const ReferenceFieldValue&>(fval)); if (val.hasValidDocumentId()) { @@ -317,7 +316,7 @@ IteratorHandler::getInternalValue(const FieldValue& fval) const return std::make_unique<InvalidValue>(); } } - case ArrayFieldValue::classId: + case FieldValue::Type::ARRAY: { const auto& val(dynamic_cast<const ArrayFieldValue&>(fval)); if (val.size() == 0) { @@ -328,7 +327,7 @@ IteratorHandler::getInternalValue(const FieldValue& fval) const return std::make_unique<ArrayValue>(values); } } - case StructFieldValue::classId: + case FieldValue::Type::STRUCT: { const auto& val(dynamic_cast<const StructFieldValue&>(fval)); if (val.empty()) { @@ -342,7 +341,7 @@ IteratorHandler::getInternalValue(const FieldValue& fval) const return std::make_unique<StructValue>(values); } } - case MapFieldValue::classId: + case FieldValue::Type::MAP: { const auto& val(static_cast<const MapFieldValue&>(fval)); if (val.isEmpty()) { @@ -353,6 +352,8 @@ IteratorHandler::getInternalValue(const FieldValue& fval) const return std::make_unique<ArrayValue>(values); } } + default: + break; } LOG(warning, "Tried to use unsupported datatype %s in field comparison", fval.getDataType()->toString().c_str()); diff --git a/document/src/vespa/document/serialization/vespadocumentdeserializer.cpp b/document/src/vespa/document/serialization/vespadocumentdeserializer.cpp index 747dfbbcee6..55ea4988fc4 100644 --- a/document/src/vespa/document/serialization/vespadocumentdeserializer.cpp +++ b/document/src/vespa/document/serialization/vespadocumentdeserializer.cpp @@ -447,8 +447,6 @@ VespaDocumentDeserializer::read(ReferenceFieldValue& value) { DocumentId id; read(id); value.setDeserializedDocumentId(id); - } else { - value.clearChanged(); } } diff --git a/document/src/vespa/document/update/addfieldpathupdate.cpp b/document/src/vespa/document/update/addfieldpathupdate.cpp index 227ac34d78b..bd06451759e 100644 --- a/document/src/vespa/document/update/addfieldpathupdate.cpp +++ b/document/src/vespa/document/update/addfieldpathupdate.cpp @@ -31,7 +31,7 @@ AddFieldPathUpdate::AddFieldPathUpdate() : FieldPathUpdate(), _values() { } -AddFieldPathUpdate::~AddFieldPathUpdate() { } +AddFieldPathUpdate::~AddFieldPathUpdate() = default; FieldPathUpdate* AddFieldPathUpdate::clone() const { @@ -53,13 +53,13 @@ private: ModificationStatus AddIteratorHandler::doModify(FieldValue &fv) { - if (fv.inherits(CollectionFieldValue::classId)) { + if (fv.isCollection()) { CollectionFieldValue &cf = static_cast<CollectionFieldValue &>(fv); for (std::size_t i = 0; i < _values.size(); ++i) { cf.add(_values[i]); } } else { - vespalib::string err = make_string("Unable to add a value to a \"%s\" field value.", fv.getClass().name()); + vespalib::string err = make_string("Unable to add a value to a \"%s\" field value.", fv.className()); throw vespalib::IllegalArgumentException(err, VESPA_STRLOC); } return ModificationStatus::MODIFIED; diff --git a/document/src/vespa/document/update/addvalueupdate.cpp b/document/src/vespa/document/update/addvalueupdate.cpp index e12afd8fa63..6f6c9a93738 100644 --- a/document/src/vespa/document/update/addvalueupdate.cpp +++ b/document/src/vespa/document/update/addvalueupdate.cpp @@ -63,14 +63,14 @@ AddValueUpdate::print(std::ostream& out, bool, const std::string& indent) const bool AddValueUpdate::applyTo(FieldValue& value) const { - if (value.inherits(ArrayFieldValue::classId)) { + if (value.isA(FieldValue::Type::ARRAY)) { ArrayFieldValue& doc(static_cast<ArrayFieldValue&>(value)); doc.add(*_value); - } else if (value.inherits(WeightedSetFieldValue::classId)) { + } else if (value.isA(FieldValue::Type::WSET)) { WeightedSetFieldValue& doc(static_cast<WeightedSetFieldValue&>(value)); doc.add(*_value, _weight); } else { - std::string err = make_string("Unable to add a value to a \"%s\" field value.", value.getClass().name()); + vespalib::string err = make_string("Unable to add a value to a \"%s\" field value.", value.className()); throw IllegalStateException(err, VESPA_STRLOC); } return true; diff --git a/document/src/vespa/document/update/arithmeticvalueupdate.cpp b/document/src/vespa/document/update/arithmeticvalueupdate.cpp index b33312d8e65..e5fb5aee8af 100644 --- a/document/src/vespa/document/update/arithmeticvalueupdate.cpp +++ b/document/src/vespa/document/update/arithmeticvalueupdate.cpp @@ -2,7 +2,6 @@ #include "arithmeticvalueupdate.h" #include <vespa/document/base/field.h> #include <vespa/document/fieldvalue/fieldvalues.h> -#include <vespa/vespalib/objects/nbostream.h> #include <vespa/vespalib/util/exceptions.h> #include <vespa/vespalib/util/xmlstream.h> #include <ostream> @@ -44,25 +43,25 @@ ArithmeticValueUpdate::checkCompatibility(const Field& field) const bool ArithmeticValueUpdate::applyTo(FieldValue& value) const { - if (value.inherits(ByteFieldValue::classId)) { + if (value.isA(FieldValue::Type::BYTE)) { ByteFieldValue& bValue = static_cast<ByteFieldValue&>(value); bValue.setValue((int)applyTo(static_cast<int64_t>(bValue.getAsInt()))); - } else if (value.inherits(DoubleFieldValue::classId)) { + } else if (value.isA(FieldValue::Type::DOUBLE)) { DoubleFieldValue& dValue = static_cast<DoubleFieldValue&>(value); dValue.setValue(applyTo(dValue.getAsDouble())); - } else if (value.inherits(FloatFieldValue::classId)) { + } else if (value.isA(FieldValue::Type::FLOAT)) { FloatFieldValue& fValue = static_cast<FloatFieldValue&>(value); fValue.setValue((float)applyTo(fValue.getAsFloat())); - } else if (value.inherits(IntFieldValue::classId)) { + } else if (value.isA(FieldValue::Type::INT)) { IntFieldValue& iValue = static_cast<IntFieldValue&>(value); iValue.setValue((int)applyTo(static_cast<int64_t>(iValue.getAsInt()))); - } else if (value.inherits(LongFieldValue::classId)) { + } else if (value.isA(FieldValue::Type::LONG)) { LongFieldValue& lValue = static_cast<LongFieldValue&>(value); lValue.setValue(applyTo(lValue.getAsLong())); } else { - std::string err = vespalib::make_string( + vespalib::string err = vespalib::make_string( "Unable to perform an arithmetic update on a \"%s\" field " - "value.", value.getClass().name()); + "value.", value.className()); throw IllegalStateException(err, VESPA_STRLOC); } return true; diff --git a/document/src/vespa/document/update/assignfieldpathupdate.cpp b/document/src/vespa/document/update/assignfieldpathupdate.cpp index 9fa5f4fa441..d4cbff2aae9 100644 --- a/document/src/vespa/document/update/assignfieldpathupdate.cpp +++ b/document/src/vespa/document/update/assignfieldpathupdate.cpp @@ -3,7 +3,6 @@ #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> #include <vespa/vespalib/objects/nbostream.h> @@ -118,12 +117,11 @@ AssignValueIteratorHandler::doModify(FieldValue& fv) { if (!(*fv.getDataType() == *_newValue.getDataType())) { vespalib::string err = vespalib::make_string( "Trying to assign \"%s\" of type %s to an instance of type %s", - _newValue.toString().c_str(), _newValue.getClass().name(), - fv.getClass().name()); + _newValue.toString().c_str(), _newValue.className(), fv.className()); throw vespalib::IllegalArgumentException(err, VESPA_STRLOC); } if (_removeIfZero - && _newValue.inherits(NumericFieldValueBase::classId) + && _newValue.isNumeric() && static_cast<const NumericFieldValueBase&>(_newValue).getAsLong() == 0) { return ModificationStatus::REMOVED; @@ -135,13 +133,13 @@ AssignValueIteratorHandler::doModify(FieldValue& fv) { ModificationStatus AssignExpressionIteratorHandler::doModify(FieldValue& fv) { LOG(spam, "fv = %s", fv.toString().c_str()); - if (fv.inherits(NumericFieldValueBase::classId)) { + if (fv.isNumeric()) { std::unique_ptr<select::VariableMap> varHolder = std::make_unique<select::VariableMap>(); select::VariableMap & vars = *varHolder; for (VariableMap::const_iterator i(getVariables().begin()), e(getVariables().end()); i != e; ++i) { - if (i->second.key.get() && i->second.key->inherits(NumericFieldValueBase::classId)) { + if (i->second.key.get() && i->second.key->isNumeric()) { vars[i->first] = i->second.key->getAsDouble(); } else { vars[i->first] = i->second.index; diff --git a/document/src/vespa/document/update/assignvalueupdate.cpp b/document/src/vespa/document/update/assignvalueupdate.cpp index d6eb0b501d3..cf2321dbf56 100644 --- a/document/src/vespa/document/update/assignvalueupdate.cpp +++ b/document/src/vespa/document/update/assignvalueupdate.cpp @@ -71,7 +71,7 @@ AssignValueUpdate::applyTo(FieldValue& value) const !value.getDataType()->isValueType(*_value))) { vespalib::string err = vespalib::make_string( "Unable to assign a \"%s\" value to a \"%s\" field value.", - _value->getClass().name(), value.getClass().name()); + _value->className(), value.className()); throw IllegalStateException(err, VESPA_STRLOC); } if (_value) { diff --git a/document/src/vespa/document/update/documentupdate.h b/document/src/vespa/document/update/documentupdate.h index 69f22237c8f..c7ebe913d79 100644 --- a/document/src/vespa/document/update/documentupdate.h +++ b/document/src/vespa/document/update/documentupdate.h @@ -40,13 +40,14 @@ class VespaDocumentSerializer; * path updates was added, and a new serialization format was * introduced while keeping the old one. */ -class DocumentUpdate final : public Printable, public XmlSerializable +class DocumentUpdate final : public Printable, public vespalib::xml::XmlSerializable { public: - typedef std::unique_ptr<DocumentUpdate> UP; - typedef std::shared_ptr<DocumentUpdate> SP; - typedef std::vector<FieldUpdate> FieldUpdateV; - typedef std::vector<FieldPathUpdate::CP> FieldPathUpdateV; + using UP = std::unique_ptr<DocumentUpdate>; + using SP = std::shared_ptr<DocumentUpdate>; + using FieldUpdateV = std::vector<FieldUpdate>; + using FieldPathUpdateV = std::vector<FieldPathUpdate::CP>; + using XmlOutputStream = vespalib::xml::XmlOutputStream; /** * Create new style document update, possibly with field path updates. diff --git a/document/src/vespa/document/update/fieldpathupdate.h b/document/src/vespa/document/update/fieldpathupdate.h index 5283f0da455..28faad722d4 100644 --- a/document/src/vespa/document/update/fieldpathupdate.h +++ b/document/src/vespa/document/update/fieldpathupdate.h @@ -4,6 +4,7 @@ #include "updatevisitor.h" #include <vespa/document/base/fieldpath.h> #include <vespa/document/util/printable.h> +#include <vespa/document/util/identifiableid.h> namespace document { diff --git a/document/src/vespa/document/update/fieldupdate.h b/document/src/vespa/document/update/fieldupdate.h index 1e4137b9531..e364e5db5fd 100644 --- a/document/src/vespa/document/update/fieldupdate.h +++ b/document/src/vespa/document/update/fieldupdate.h @@ -23,7 +23,7 @@ class DocumentType; class FieldUpdate : public vespalib::Identifiable, public Printable, - public XmlSerializable + public vespalib::xml::XmlSerializable { Field _field; std::vector<ValueUpdate::CP> _updates; @@ -31,6 +31,7 @@ class FieldUpdate : public vespalib::Identifiable, public: typedef vespalib::CloneablePtr<FieldUpdate> CP; + using XmlOutputStream = vespalib::xml::XmlOutputStream; FieldUpdate(const Field& field); FieldUpdate(const FieldUpdate &); diff --git a/document/src/vespa/document/update/mapvalueupdate.cpp b/document/src/vespa/document/update/mapvalueupdate.cpp index 18f2c013b7f..48e52a9d2cc 100644 --- a/document/src/vespa/document/update/mapvalueupdate.cpp +++ b/document/src/vespa/document/update/mapvalueupdate.cpp @@ -44,7 +44,7 @@ MapValueUpdate::checkCompatibility(const Field& field) const { // Check compatibility of nested types. if (field.getDataType().isArray()) { - if (_key->getClass().id() != IntFieldValue::classId) { + if ( !_key->isA(FieldValue::Type::INT)) { throw IllegalArgumentException(vespalib::make_string( "Key for field '%s' is of wrong type (expected '%s', was '%s').", field.getName().data(), DataType::INT->toString().c_str(), @@ -60,7 +60,7 @@ MapValueUpdate::checkCompatibility(const Field& field) const } } else { throw IllegalArgumentException("MapValueUpdate does not support " - "datatype " + field.getDataType().toString() + ".", VESPA_STRLOC); + "datatype " + field.getDataType().toString() + ".", VESPA_STRLOC); } } diff --git a/document/src/vespa/document/update/removevalueupdate.cpp b/document/src/vespa/document/update/removevalueupdate.cpp index d35d8db84a2..a61553da4d1 100644 --- a/document/src/vespa/document/update/removevalueupdate.cpp +++ b/document/src/vespa/document/update/removevalueupdate.cpp @@ -56,14 +56,14 @@ RemoveValueUpdate::checkCompatibility(const Field& field) const bool RemoveValueUpdate::applyTo(FieldValue& value) const { - if (value.inherits(ArrayFieldValue::classId)) { + if (value.isA(FieldValue::Type::ARRAY)) { ArrayFieldValue& doc(static_cast<ArrayFieldValue&>(value)); doc.remove(*_key); - } else if (value.inherits(WeightedSetFieldValue::classId)) { + } else if (value.isA(FieldValue::Type::WSET)) { WeightedSetFieldValue& doc(static_cast<WeightedSetFieldValue&>(value)); doc.remove(*_key); } else { - std::string err = vespalib::make_string("Unable to remove a value from a \"%s\" field value.", value.getClass().name()); + std::string err = vespalib::make_string("Unable to remove a value from a \"%s\" field value.", value.className()); throw IllegalStateException(err, VESPA_STRLOC); } return true; diff --git a/document/src/vespa/document/update/tensor_add_update.cpp b/document/src/vespa/document/update/tensor_add_update.cpp index 3b442b7b1d5..1f8aed2d8b4 100644 --- a/document/src/vespa/document/update/tensor_add_update.cpp +++ b/document/src/vespa/document/update/tensor_add_update.cpp @@ -8,10 +8,8 @@ #include <vespa/document/fieldvalue/document.h> #include <vespa/document/fieldvalue/tensorfieldvalue.h> #include <vespa/document/serialization/vespadocumentdeserializer.h> -#include <vespa/document/util/serializableexceptions.h> #include <vespa/eval/eval/value.h> #include <vespa/eval/eval/fast_value.h> -#include <vespa/vespalib/objects/nbostream.h> #include <vespa/vespalib/stllike/asciistream.h> #include <vespa/vespalib/util/stringfmt.h> #include <vespa/vespalib/util/xmlstream.h> @@ -99,7 +97,7 @@ TensorAddUpdate::apply_to(const Value &old_tensor, bool TensorAddUpdate::applyTo(FieldValue& value) const { - if (value.inherits(TensorFieldValue::classId)) { + if (value.isA(FieldValue::Type::TENSOR)) { TensorFieldValue &tensorFieldValue = static_cast<TensorFieldValue &>(value); tensorFieldValue.make_empty_if_not_existing(); auto oldTensor = tensorFieldValue.getAsTensorPtr(); @@ -110,7 +108,7 @@ TensorAddUpdate::applyTo(FieldValue& value) const } } else { vespalib::string err = make_string("Unable to perform a tensor add update on a '%s' field value", - value.getClass().name()); + value.className()); throw IllegalStateException(err, VESPA_STRLOC); } return true; @@ -136,11 +134,11 @@ void TensorAddUpdate::deserialize(const DocumentTypeRepo &repo, const DataType &type, nbostream & stream) { auto tensor = type.createFieldValue(); - if (tensor->inherits(TensorFieldValue::classId)) { + if (tensor->isA(FieldValue::Type::TENSOR)) { _tensor.reset(static_cast<TensorFieldValue *>(tensor.release())); } else { vespalib::string err = make_string("Expected tensor field value, got a '%s' field value", - tensor->getClass().name()); + tensor->className()); throw IllegalStateException(err, VESPA_STRLOC); } VespaDocumentDeserializer deserializer(repo, stream, Document::getNewestSerializationVersion()); diff --git a/document/src/vespa/document/update/tensor_modify_update.cpp b/document/src/vespa/document/update/tensor_modify_update.cpp index 91ac6f4c754..49ea57f28c1 100644 --- a/document/src/vespa/document/update/tensor_modify_update.cpp +++ b/document/src/vespa/document/update/tensor_modify_update.cpp @@ -94,7 +94,7 @@ TensorModifyUpdate::TensorModifyUpdate() TensorModifyUpdate::TensorModifyUpdate(const TensorModifyUpdate &rhs) : _operation(rhs._operation), _tensorType(std::make_unique<TensorDataType>(*rhs._tensorType)), - _tensor(Identifiable::cast<TensorFieldValue *>(_tensorType->createFieldValue().release())) + _tensor(static_cast<TensorFieldValue *>(_tensorType->createFieldValue().release())) { *_tensor = *rhs._tensor; } @@ -102,7 +102,7 @@ TensorModifyUpdate::TensorModifyUpdate(const TensorModifyUpdate &rhs) TensorModifyUpdate::TensorModifyUpdate(Operation operation, std::unique_ptr<TensorFieldValue> tensor) : _operation(operation), _tensorType(std::make_unique<TensorDataType>(dynamic_cast<const TensorDataType &>(*tensor->getDataType()))), - _tensor(Identifiable::cast<TensorFieldValue *>(_tensorType->createFieldValue().release())) + _tensor(static_cast<TensorFieldValue *>(_tensorType->createFieldValue().release())) { *_tensor = *tensor; } @@ -116,7 +116,7 @@ TensorModifyUpdate::operator=(const TensorModifyUpdate &rhs) _operation = rhs._operation; _tensor.reset(); _tensorType = std::make_unique<TensorDataType>(*rhs._tensorType); - _tensor.reset(Identifiable::cast<TensorFieldValue *>(_tensorType->createFieldValue().release())); + _tensor.reset(dynamic_cast<TensorFieldValue *>(_tensorType->createFieldValue().release())); *_tensor = *rhs._tensor; } return *this; @@ -177,7 +177,7 @@ TensorModifyUpdate::apply_to(const Value &old_tensor, bool TensorModifyUpdate::applyTo(FieldValue& value) const { - if (value.inherits(TensorFieldValue::classId)) { + if (value.isA(FieldValue::Type::TENSOR)) { TensorFieldValue &tensorFieldValue = static_cast<TensorFieldValue &>(value); auto oldTensor = tensorFieldValue.getAsTensorPtr(); if (oldTensor) { @@ -188,7 +188,7 @@ TensorModifyUpdate::applyTo(FieldValue& value) const } } else { vespalib::string err = make_string("Unable to perform a tensor modify update on a '%s' field value", - value.getClass().name()); + value.className()); throw IllegalStateException(err, VESPA_STRLOC); } return true; @@ -241,11 +241,11 @@ TensorModifyUpdate::deserialize(const DocumentTypeRepo &repo, const DataType &ty _operation = static_cast<Operation>(op); _tensorType = convertToCompatibleType(dynamic_cast<const TensorDataType &>(type)); auto tensor = _tensorType->createFieldValue(); - if (tensor->inherits(TensorFieldValue::classId)) { + if (tensor->isA(FieldValue::Type::TENSOR)) { _tensor.reset(static_cast<TensorFieldValue *>(tensor.release())); } else { vespalib::string err = make_string("Expected tensor field value, got a '%s' field value", - tensor->getClass().name()); + tensor->className()); throw IllegalStateException(err, VESPA_STRLOC); } VespaDocumentDeserializer deserializer(repo, stream, Document::getNewestSerializationVersion()); diff --git a/document/src/vespa/document/update/tensor_remove_update.cpp b/document/src/vespa/document/update/tensor_remove_update.cpp index f4dc9490b62..f2d11ef8234 100644 --- a/document/src/vespa/document/update/tensor_remove_update.cpp +++ b/document/src/vespa/document/update/tensor_remove_update.cpp @@ -54,7 +54,7 @@ TensorRemoveUpdate::TensorRemoveUpdate(const TensorRemoveUpdate &rhs) TensorRemoveUpdate::TensorRemoveUpdate(std::unique_ptr<TensorFieldValue> tensor) : _tensorType(std::make_unique<TensorDataType>(dynamic_cast<const TensorDataType &>(*tensor->getDataType()))), - _tensor(Identifiable::cast<TensorFieldValue *>(_tensorType->createFieldValue().release())) + _tensor(static_cast<TensorFieldValue *>(_tensorType->createFieldValue().release())) { *_tensor = *tensor; } @@ -67,7 +67,7 @@ TensorRemoveUpdate::operator=(const TensorRemoveUpdate &rhs) if (&rhs != this) { _tensor.reset(); _tensorType = std::make_unique<TensorDataType>(*rhs._tensorType); - _tensor.reset(Identifiable::cast<TensorFieldValue *>(_tensorType->createFieldValue().release())); + _tensor.reset(static_cast<TensorFieldValue *>(_tensorType->createFieldValue().release())); *_tensor = *rhs._tensor; } return *this; @@ -122,7 +122,7 @@ TensorRemoveUpdate::apply_to(const Value &old_tensor, bool TensorRemoveUpdate::applyTo(FieldValue &value) const { - if (value.inherits(TensorFieldValue::classId)) { + if (value.isA(FieldValue::Type::TENSOR)) { TensorFieldValue &tensorFieldValue = static_cast<TensorFieldValue &>(value); auto oldTensor = tensorFieldValue.getAsTensorPtr(); if (oldTensor) { @@ -133,7 +133,7 @@ TensorRemoveUpdate::applyTo(FieldValue &value) const } } else { vespalib::string err = make_string("Unable to perform a tensor remove update on a '%s' field value", - value.getClass().name()); + value.className()); throw IllegalStateException(err, VESPA_STRLOC); } return true; diff --git a/document/src/vespa/document/update/valueupdate.h b/document/src/vespa/document/update/valueupdate.h index 9a8ed4e9537..ec903c1adc1 100644 --- a/document/src/vespa/document/update/valueupdate.h +++ b/document/src/vespa/document/update/valueupdate.h @@ -20,9 +20,9 @@ #include "updatevisitor.h" #include <vespa/document/util/printable.h> -#include <vespa/document/util/xmlserializable.h> #include <vespa/document/util/identifiableid.h> #include <vespa/vespalib/objects/nbostream.h> +#include <vespa/vespalib/util/xmlserializable.h> namespace document { @@ -33,12 +33,13 @@ class DataType; class ValueUpdate : public vespalib::Identifiable, public Printable, - public XmlSerializable + public vespalib::xml::XmlSerializable { protected: using nbostream = vespalib::nbostream; public: using CP = vespalib::CloneablePtr<ValueUpdate>; + using XmlOutputStream = vespalib::xml::XmlOutputStream; /** * Create a value update object from the given stream. diff --git a/document/src/vespa/document/util/feed_reject_helper.cpp b/document/src/vespa/document/util/feed_reject_helper.cpp index f23524eddfb..a6829ec0c60 100644 --- a/document/src/vespa/document/util/feed_reject_helper.cpp +++ b/document/src/vespa/document/util/feed_reject_helper.cpp @@ -4,14 +4,12 @@ #include <vespa/document/update/documentupdate.h> #include <vespa/document/update/assignvalueupdate.h> #include <vespa/document/fieldvalue/boolfieldvalue.h> -#include <vespa/document/fieldvalue/numericfieldvalue.h> - namespace document { bool FeedRejectHelper::isFixedSizeSingleValue(const document::FieldValue & fv) { - return fv.inherits(BoolFieldValue::classId) || fv.inherits(NumericFieldValueBase::classId); + return fv.isFixedSizeSingleValue(); } bool diff --git a/document/src/vespa/document/util/xmlserializable.h b/document/src/vespa/document/util/xmlserializable.h deleted file mode 100644 index f4a5db0de58..00000000000 --- a/document/src/vespa/document/util/xmlserializable.h +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <vespa/vespalib/util/xmlserializable.h> - -namespace document { - using XmlSerializable = vespalib::xml::XmlSerializable; - using XmlOutputStream = vespalib::xml::XmlOutputStream; -} diff --git a/searchcore/src/vespa/searchcore/proton/attribute/document_field_extractor.cpp b/searchcore/src/vespa/searchcore/proton/attribute/document_field_extractor.cpp index 1c779be18be..c0c6f729509 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/document_field_extractor.cpp +++ b/searchcore/src/vespa/searchcore/proton/attribute/document_field_extractor.cpp @@ -110,13 +110,6 @@ makeArray(const FieldPathEntry &fieldPathEntry, size_t size) return array; } -bool -checkInherits(const FieldValue &fieldValue, unsigned id) -{ - const vespalib::Identifiable::RuntimeClass &rc = fieldValue.getClass(); - return rc.inherits(id); -} - } DocumentFieldExtractor::DocumentFieldExtractor(const Document &doc) @@ -176,7 +169,7 @@ template <typename ExtractorFunc> std::unique_ptr<FieldValue> extractFieldFromMap(const FieldValue *outerFieldValue, const FieldPathEntry &innerEntry, ExtractorFunc &&extractor) { - if (outerFieldValue != nullptr && checkInherits(*outerFieldValue, MapFieldValue::classId)) { + if (outerFieldValue && outerFieldValue->isA(FieldValue::Type::MAP)) { const auto outerMap = static_cast<const MapFieldValue *>(outerFieldValue); auto array = makeArray(innerEntry, outerMap->size()); uint32_t arrayIndex = 0; @@ -190,9 +183,9 @@ extractFieldFromMap(const FieldValue *outerFieldValue, const FieldPathEntry &inn template <typename CollectionFieldValueT, typename ExtractorFunc> std::unique_ptr<FieldValue> -extractFieldFromStructCollection(const FieldValue *outerFieldValue, const FieldPathEntry &innerEntry, ExtractorFunc &&extractor) +extractFieldFromStructCollection(const FieldValue *outerFieldValue, FieldValue::Type expectedType, const FieldPathEntry &innerEntry, ExtractorFunc &&extractor) { - if (outerFieldValue != nullptr && checkInherits(*outerFieldValue, CollectionFieldValueT::classId)) { + if (outerFieldValue && outerFieldValue->isA(expectedType)) { const auto *outerCollection = static_cast<const CollectionFieldValueT *>(outerFieldValue); auto array = makeArray(innerEntry, outerCollection->size()); uint32_t arrayIndex = 0; @@ -213,7 +206,7 @@ extractFieldFromStructCollection(const FieldValue *outerFieldValue, const FieldP std::unique_ptr<FieldValue> DocumentFieldExtractor::extractFieldFromStructArray(const FieldPath &fieldPath) { - return extractFieldFromStructCollection<ArrayFieldValue>(getCachedFieldValue(fieldPath[0]), fieldPath[1], + return extractFieldFromStructCollection<ArrayFieldValue>(getCachedFieldValue(fieldPath[0]), FieldValue::Type::ARRAY, fieldPath[1], [](const auto *elem){ return elem; }); } @@ -234,7 +227,7 @@ DocumentFieldExtractor::extractValueFieldFromPrimitiveMap(const FieldPath &field std::unique_ptr<document::FieldValue> DocumentFieldExtractor::extractValueFieldFromStructMap(const FieldPath &fieldPath) { - return extractFieldFromStructCollection<MapFieldValue>(getCachedFieldValue(fieldPath[0]), fieldPath[2], + return extractFieldFromStructCollection<MapFieldValue>(getCachedFieldValue(fieldPath[0]), FieldValue::Type::MAP, fieldPath[2], [](const auto *elem){ return elem->second; }); } diff --git a/searchcore/src/vespa/searchcore/proton/attribute/document_field_retriever.cpp b/searchcore/src/vespa/searchcore/proton/attribute/document_field_retriever.cpp index 00d84e795c7..cf543f1ba17 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/document_field_retriever.cpp +++ b/searchcore/src/vespa/searchcore/proton/attribute/document_field_retriever.cpp @@ -58,7 +58,7 @@ setValue(DocumentIdT lid, Document &doc, const document::Field & field, const IA break; } FieldValue::UP fv = field.getDataType().createFieldValue(); - if (fv.get() && fv->getClass().id() != ArrayFieldValue::classId) { + if (fv && ! fv->isA(FieldValue::Type::ARRAY)) { throw IllegalStateException("Field " + field.getName() + " does not contain an array.", VESPA_STRLOC); } ArrayFieldValue &array = static_cast<ArrayFieldValue &>(*fv.get()); @@ -78,7 +78,7 @@ setValue(DocumentIdT lid, Document &doc, const document::Field & field, const IA break; } FieldValue::UP fv = field.getDataType().createFieldValue(); - if (fv.get() && fv->getClass().id() != WeightedSetFieldValue::classId) { + if (fv && ! fv->isA(FieldValue::Type::WSET)) { throw IllegalStateException("Field " + field.getName() + " does not contain a wset.", VESPA_STRLOC); } WeightedSetFieldValue & wset(static_cast<WeightedSetFieldValue &>(*fv.get())); diff --git a/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp b/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp index 9c7b4bbb4b7..5b134c65e84 100644 --- a/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp +++ b/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp @@ -136,16 +136,15 @@ AttributeUpdater::handleUpdateT(V & vec, Accessor, uint32_t lid, const ValueUpda const AssignValueUpdate & assign(static_cast<const AssignValueUpdate &>(upd)); if (assign.hasValue()) { const FieldValue & fv(assign.getValue()); - const vespalib::Identifiable::RuntimeClass & rc(fv.getClass()); - if (rc.inherits(ArrayFieldValue::classId)) { + if (fv.isA(FieldValue::Type::ARRAY)) { ArrayAccessor<Accessor> ac(static_cast<const ArrayFieldValue & >(fv)); appendValue(vec, lid, ac); - } else if (rc.inherits(WeightedSetFieldValue::classId)) { + } else if (fv.isA(FieldValue::Type::WSET)) { WeightedSetAccessor<Accessor> ac(static_cast<const WeightedSetFieldValue & >(fv)); appendValue(vec, lid, ac); } else { LOG(warning, "Unsupported value %s in assign operation on multivalue vector %s", - rc.name(), vec.getName().c_str()); + fv.className(), vec.getName().c_str()); } } } else if (op == ValueUpdate::Add) { @@ -158,7 +157,7 @@ AttributeUpdater::handleUpdateT(V & vec, Accessor, uint32_t lid, const ValueUpda const MapValueUpdate & map(static_cast<const MapValueUpdate &>(upd)); if (!vec.AttributeVector::apply(lid, map)) { throw UpdateException(make_string("attribute map(%s, %s) failed: %s[%u]", - map.getKey().getClass().name(), map.getUpdate().getClass().name(), + map.getKey().className(), map.getUpdate().getClass().name(), vec.getName().c_str(), lid)); } } else { @@ -323,15 +322,14 @@ AttributeUpdater::handleValueT(V & vec, Accessor, uint32_t lid, const FieldValue { if (vec.hasMultiValue()) { vec.clearDoc(lid); - const vespalib::Identifiable::RuntimeClass & rc = val.getClass(); - if (rc.inherits(ArrayFieldValue::classId)) { + if (val.isA(FieldValue::Type::ARRAY)) { ArrayAccessor<Accessor> ac(static_cast<const ArrayFieldValue & >(val)); appendValue(vec, lid, ac); - } else if (rc.inherits(WeightedSetFieldValue::classId)) { + } else if (val.isA(FieldValue::Type::WSET)) { WeightedSetAccessor<Accessor> ac(static_cast<const WeightedSetFieldValue & >(val)); appendValue(vec, lid, ac); } else { - LOG(warning, "Unsupported value '%s' to assign on multivalue vector '%s'", rc.name(), vec.getName().c_str()); + LOG(warning, "Unsupported value '%s' to assign on multivalue vector '%s'", val.className(), vec.getName().c_str()); } } else { updateValue(vec, lid, val); @@ -412,7 +410,7 @@ namespace { const vespalib::string & getString(const search::StringAttribute & attr, uint32_t lid, const FieldValue & val) { - if ( ! val.inherits(LiteralFieldValueB::classId) ) { + if ( ! val.isLiteral() ) { throw UpdateException(make_string("Can not update a string attribute '%s' for lid=%d from a non-literal fieldvalue: %s", attr.getName().c_str(), lid, val.toString().c_str())); } @@ -453,11 +451,10 @@ AttributeUpdater::updateValue(StringAttribute & vec, uint32_t lid, const FieldVa namespace { -template <typename ExpFieldValueType> void -validate_field_value_type(const FieldValue& val, const vespalib::string& attr_type, const vespalib::string& value_type) +validate_field_value_type(FieldValue::Type expectedType, const FieldValue& val, const vespalib::string& attr_type, const vespalib::string& value_type) { - if (!val.inherits(ExpFieldValueType::classId)) { + if (!val.isA(expectedType)) { throw UpdateException( make_string("%s must be updated with %s, but was '%s'", attr_type.c_str(), value_type.c_str(), val.toString(false).c_str())); @@ -469,14 +466,14 @@ validate_field_value_type(const FieldValue& val, const vespalib::string& attr_ty void AttributeUpdater::updateValue(PredicateAttribute &vec, uint32_t lid, const FieldValue &val) { - validate_field_value_type<PredicateFieldValue>(val, "PredicateAttribute", "PredicateFieldValue"); + validate_field_value_type(FieldValue::Type::PREDICATE, val, "PredicateAttribute", "PredicateFieldValue"); vec.updateValue(lid, static_cast<const PredicateFieldValue &>(val)); } void AttributeUpdater::updateValue(TensorAttribute &vec, uint32_t lid, const FieldValue &val) { - validate_field_value_type<TensorFieldValue>(val, "TensorAttribute", "TensorFieldValue"); + validate_field_value_type(FieldValue::Type::TENSOR, val, "TensorAttribute", "TensorFieldValue"); const auto &tensor = static_cast<const TensorFieldValue &>(val).getAsTensorPtr(); if (tensor) { vec.setTensor(lid, *tensor); @@ -488,7 +485,7 @@ AttributeUpdater::updateValue(TensorAttribute &vec, uint32_t lid, const FieldVal void AttributeUpdater::updateValue(ReferenceAttribute &vec, uint32_t lid, const FieldValue &val) { - if (!val.inherits(ReferenceFieldValue::classId)) { + if (!val.isA(FieldValue::Type::REFERENCE)) { vec.clearDoc(lid); throw UpdateException( make_string("ReferenceAttribute must be updated with " @@ -518,7 +515,7 @@ validate_tensor_attribute_type(AttributeVector& attr) std::unique_ptr<PrepareResult> prepare_set_tensor(TensorAttribute& attr, uint32_t docid, const FieldValue& val) { - validate_field_value_type<TensorFieldValue>(val, "TensorAttribute", "TensorFieldValue"); + validate_field_value_type(FieldValue::Type::TENSOR, val, "TensorAttribute", "TensorFieldValue"); const auto& tensor = static_cast<const TensorFieldValue&>(val).getAsTensorPtr(); if (tensor) { return attr.prepare_set_tensor(docid, *tensor); @@ -529,7 +526,7 @@ prepare_set_tensor(TensorAttribute& attr, uint32_t docid, const FieldValue& val) void complete_set_tensor(TensorAttribute& attr, uint32_t docid, const FieldValue& val, std::unique_ptr<PrepareResult> prepare_result) { - validate_field_value_type<TensorFieldValue>(val, "TensorAttribute", "TensorFieldValue"); + validate_field_value_type(FieldValue::Type::TENSOR, val, "TensorAttribute", "TensorFieldValue"); const auto& tensor = static_cast<const TensorFieldValue&>(val).getAsTensorPtr(); if (tensor) { attr.complete_set_tensor(docid, *tensor, std::move(prepare_result)); diff --git a/searchcore/src/vespa/searchcore/proton/docsummary/documentstoreadapter.cpp b/searchcore/src/vespa/searchcore/proton/docsummary/documentstoreadapter.cpp index 1342324b727..3550b38383a 100644 --- a/searchcore/src/vespa/searchcore/proton/docsummary/documentstoreadapter.cpp +++ b/searchcore/src/vespa/searchcore/proton/docsummary/documentstoreadapter.cpp @@ -58,7 +58,7 @@ DocumentStoreAdapter::writeField(const FieldValue &value, ResType type) case RES_LONG_STRING: case RES_JSONSTRING: { - if (value.getClass().inherits(LiteralFieldValueB::classId)) { + if (value.isLiteral()) { auto & lfv = static_cast<const LiteralFieldValueB &>(value); vespalib::stringref s = lfv.getValueRef(); return writeStringField(s.data(), s.size(), type); @@ -80,7 +80,7 @@ DocumentStoreAdapter::writeField(const FieldValue &value, ResType type) case RES_TENSOR: { vespalib::nbostream serialized; - if (value.getClass().inherits(TensorFieldValue::classId)) { + if (value.isA(FieldValue::Type::TENSOR)) { const auto &tvalue = static_cast<const TensorFieldValue &>(value); auto tensor = tvalue.getAsTensorPtr(); if (tensor) { diff --git a/searchlib/src/vespa/searchlib/attribute/attributevector.hpp b/searchlib/src/vespa/searchlib/attribute/attributevector.hpp index 623e10ef052..c75f7788467 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributevector.hpp +++ b/searchlib/src/vespa/searchlib/attribute/attributevector.hpp @@ -10,23 +10,6 @@ namespace search { -template <typename T> -inline bool myIsNan(T v) { (void)v; return false; } - -template <> -inline bool -myIsNan<float>(float v) -{ - return std::isnan(v); -} - -template <> -inline bool -myIsNan<double>(double v) -{ - return std::isnan(v); -} - template<typename T> bool AttributeVector::adjustWeight(ChangeVectorT< ChangeTemplate<T> > & changes, DocId doc, const T & v, @@ -70,7 +53,7 @@ AttributeVector::adjustWeight(ChangeVectorT< ChangeTemplate<T> >& changes, DocId size_t oldSz(changes.size()); if (wu.hasValue()) { const FieldValue &wv = wu.getValue(); - if (wv.inherits(document::IntFieldValue::classId)) { + if (wv.isA(FieldValue::Type::INT)) { changes.push_back(ChangeTemplate<T>(ChangeBase::SETWEIGHT, doc, v, wv.getAsInt())); } else { retval = false; diff --git a/searchlib/src/vespa/searchlib/expression/documentfieldnode.cpp b/searchlib/src/vespa/searchlib/expression/documentfieldnode.cpp index df3d2e5b19b..91e5a36a7cf 100644 --- a/searchlib/src/vespa/searchlib/expression/documentfieldnode.cpp +++ b/searchlib/src/vespa/searchlib/expression/documentfieldnode.cpp @@ -29,11 +29,12 @@ DocumentFieldNode::DocumentFieldNode(const DocumentFieldNode & rhs) : _fieldPath(rhs._fieldPath), _value(rhs._value), _fieldName(rhs._fieldName), - _doc(NULL) + _doc(nullptr) { } -DocumentFieldNode & DocumentFieldNode::operator = (const DocumentFieldNode & rhs) +DocumentFieldNode & +DocumentFieldNode::operator = (const DocumentFieldNode & rhs) { if (this != &rhs) { DocumentAccessorNode::operator=(rhs); @@ -49,12 +50,11 @@ std::unique_ptr<ResultNode> deduceResultNode(vespalib::stringref fieldName, const FieldValue & fv, bool preserveAccurateTypes, bool nestedMultiValue) { std::unique_ptr<ResultNode> value; - const Identifiable::RuntimeClass & cInfo = fv.getClass(); - if (cInfo.inherits(ByteFieldValue::classId) || cInfo.inherits(IntFieldValue::classId) || cInfo.inherits(LongFieldValue::classId)) { + if (fv.isA(FieldValue::Type::BYTE) || fv.isA(FieldValue::Type::INT) || fv.isA(FieldValue::Type::LONG)) { if (preserveAccurateTypes) { - if (cInfo.inherits(ByteFieldValue::classId)) { + if (fv.isA(FieldValue::Type::BYTE)) { value.reset(nestedMultiValue ? static_cast<ResultNode *>(new Int8ResultNodeVector()) : static_cast<ResultNode *>(new Int8ResultNode())); - } else if (cInfo.inherits(IntFieldValue::classId)) { + } else if (fv.isA(FieldValue::Type::INT)) { value.reset(nestedMultiValue ? static_cast<ResultNode *>(new Int32ResultNodeVector()) : static_cast<ResultNode *>(new Int32ResultNode())); } else { value.reset(nestedMultiValue ? static_cast<ResultNode *>(new Int64ResultNodeVector()) : static_cast<ResultNode *>(new Int64ResultNode())); @@ -62,22 +62,20 @@ deduceResultNode(vespalib::stringref fieldName, const FieldValue & fv, bool pres } else { value.reset(nestedMultiValue ? static_cast<ResultNode *>(new Int64ResultNodeVector()) : static_cast<ResultNode *>(new Int64ResultNode())); } - } else if (cInfo.inherits(FloatFieldValue::classId) || cInfo.inherits(DoubleFieldValue::classId)) { + } else if (fv.isA(FieldValue::Type::FLOAT) || fv.isA(FieldValue::Type::DOUBLE)) { value.reset(nestedMultiValue ? static_cast<ResultNode *>(new FloatResultNodeVector()) : static_cast<ResultNode *>(new FloatResultNode())); - } else if (cInfo.inherits(BoolFieldValue::classId)) { + } else if (fv.isA(FieldValue::Type::BOOL)) { value.reset(nestedMultiValue ? static_cast<ResultNode *>(new BoolResultNodeVector()) : static_cast<ResultNode *>(new BoolResultNode())); - } else if (cInfo.inherits(StringFieldValue::classId)) { + } else if (fv.isA(FieldValue::Type::STRING)) { value.reset(nestedMultiValue ? static_cast<ResultNode *>(new StringResultNodeVector()) : static_cast<ResultNode *>(new StringResultNode())); - } else if (cInfo.inherits(RawFieldValue::classId)) { + } else if (fv.isA(FieldValue::Type::RAW)) { value.reset(nestedMultiValue ? static_cast<ResultNode *>(new RawResultNodeVector()) : static_cast<ResultNode *>(new RawResultNode())); - } else if (cInfo.inherits(CollectionFieldValue::classId) || cInfo.inherits(MapFieldValue::classId)) { - if (cInfo.inherits(CollectionFieldValue::classId)) { + } else if (fv.isCollection() || fv.isA(FieldValue::Type::MAP)) { + if (fv.isCollection()) { value = deduceResultNode(fieldName, *static_cast<const CollectionFieldValue &>(fv).createNested(), preserveAccurateTypes, nestedMultiValue); - } else if (cInfo.inherits(MapFieldValue::classId)) { - value = deduceResultNode(fieldName, *static_cast<const MapFieldValue &>(fv).createValue(), preserveAccurateTypes, nestedMultiValue); } else { - throw std::runtime_error(make_string("Can not deduce correct resultclass for documentfield '%s' in based on class '%s'", - vespalib::string(fieldName).c_str(), cInfo.name())); + assert(fv.isA(FieldValue::Type::MAP)); + value = deduceResultNode(fieldName, *static_cast<const MapFieldValue &>(fv).createValue(), preserveAccurateTypes, nestedMultiValue); } const Identifiable::RuntimeClass & rInfo = value->getClass(); if (rInfo.inherits(ResultNodeVector::classId)) { @@ -100,16 +98,17 @@ deduceResultNode(vespalib::stringref fieldName, const FieldValue & fv, bool pres value.reset(new RawResultNodeVector()); } else { throw std::runtime_error(make_string("Can not deduce correct resultclass for documentfield '%s' in based on class '%s'. It nests down to %s which is not expected", - vespalib::string(fieldName).c_str(), cInfo.name(), rInfo.name())); + vespalib::string(fieldName).c_str(), fv.className(), rInfo.name())); } } else { throw std::runtime_error(make_string("Can not deduce correct resultclass for documentfield '%s' in based on class '%s'", - vespalib::string(fieldName).c_str(), cInfo.name())); + vespalib::string(fieldName).c_str(), fv.className())); } return value; } -void DocumentFieldNode::onPrepare(bool preserveAccurateTypes) +void +DocumentFieldNode::onPrepare(bool preserveAccurateTypes) { LOG(debug, "DocumentFieldNode::onPrepare(this=%p)", this); @@ -118,8 +117,8 @@ void DocumentFieldNode::onPrepare(bool preserveAccurateTypes) for(document::FieldPath::const_iterator it(_fieldPath.begin()), mt(_fieldPath.end()); !nestedMultiValue && (it != mt); it++) { const FieldPathEntry & fpe = **it; if (fpe.getType() == document::FieldPathEntry::STRUCT_FIELD) { - const vespalib::Identifiable::RuntimeClass & cInfo(fpe.getFieldValueToSet().getClass()); - nestedMultiValue = cInfo.inherits(CollectionFieldValue::classId) || cInfo.inherits(MapFieldValue::classId); + const FieldValue & fv = fpe.getFieldValueToSet(); + nestedMultiValue = fv.isCollection() || fv.isA(FieldValue::Type::MAP); } } const document::FieldPathEntry & endOfPath(_fieldPath.back()); @@ -127,9 +126,9 @@ void DocumentFieldNode::onPrepare(bool preserveAccurateTypes) const FieldValue& fv = endOfPath.getFieldValueToSet(); _value.reset(deduceResultNode(_fieldName, fv, preserveAccurateTypes, nestedMultiValue).release()); if (_value->inherits(ResultNodeVector::classId)) { - _handler.reset(new MultiHandler(static_cast<ResultNodeVector &>(*_value))); + _handler = std::make_unique<MultiHandler>(static_cast<ResultNodeVector &>(*_value)); } else { - _handler.reset(new SingleHandler(*_value)); + _handler = std::make_unique<SingleHandler>(*_value); } } else { if (endOfPath.getDataType().isStructured()) { @@ -222,10 +221,10 @@ DocumentFieldNode::Handler::onCollectionStart(const Content & c) { const document::FieldValue & fv = c.getValue(); LOG(spam, "onCollectionStart: field value '%s'", fv.toString().c_str()); - if (fv.inherits(document::ArrayFieldValue::classId)) { + if (fv.isA(FieldValue::Type::ARRAY)) { const document::ArrayFieldValue & afv = static_cast<const document::ArrayFieldValue &>(fv); LOG(spam, "onCollectionStart: Array size = '%zu'", afv.size()); - } else if (fv.inherits(document::WeightedSetFieldValue::classId)) { + } else if (fv.isA(FieldValue::Type::WSET)) { const document::WeightedSetFieldValue & wsfv = static_cast<const document::WeightedSetFieldValue &>(fv); LOG(spam, "onCollectionStart: WeightedSet size = '%zu'", wsfv.size()); } @@ -253,9 +252,6 @@ DocumentFieldNode::visitMembers(vespalib::ObjectVisitor &visitor) const { visit(visitor, "fieldName", _fieldName); visit(visitor, "value", _value); - visitor.openStruct("fieldPath", "FieldPath"); - _fieldPath.visitMembers(visitor); - visitor.closeStruct(); } class String2ResultNode : public ResultNode diff --git a/searchlib/src/vespa/searchlib/memoryindex/field_inverter.cpp b/searchlib/src/vespa/searchlib/memoryindex/field_inverter.cpp index a443e994559..5a7d0e60153 100644 --- a/searchlib/src/vespa/searchlib/memoryindex/field_inverter.cpp +++ b/searchlib/src/vespa/searchlib/memoryindex/field_inverter.cpp @@ -271,7 +271,7 @@ FieldInverter::saveWord(const vespalib::stringref word) uint32_t FieldInverter::saveWord(const document::FieldValue &fv) { - assert(fv.getClass().id() == StringFieldValue::classId); + assert(fv.isA(FieldValue::Type::STRING)); using RawRef = std::pair<const char*, size_t>; RawRef sRef = fv.getAsRaw(); return saveWord(vespalib::stringref(sRef.first, sRef.second)); @@ -303,8 +303,7 @@ FieldInverter::endDoc() } _calculator.add_field_length(field_length); uint32_t newPosSize = static_cast<uint32_t>(_positions.size()); - _pendingDocs.insert({ _docId, - { _oldPosSize, newPosSize - _oldPosSize } }); + _pendingDocs.insert({ _docId, { _oldPosSize, newPosSize - _oldPosSize } }); _docId = 0; _oldPosSize = newPosSize; } @@ -324,7 +323,7 @@ FieldInverter::processNormalDocArrayTextField(const ArrayFieldValue &field) uint32_t ele = field.size(); for (;el < ele; ++el) { const FieldValue &elfv = field[el]; - assert(elfv.getClass().id() == StringFieldValue::classId); + assert(elfv.isA(FieldValue::Type::STRING)); const auto &element = static_cast<const StringFieldValue &>(elfv); startElement(1); processAnnotations(element); @@ -338,8 +337,8 @@ FieldInverter::processNormalDocWeightedSetTextField(const WeightedSetFieldValue for (const auto & el : field) { const FieldValue &key = *el.first; const FieldValue &xweight = *el.second; - assert(key.getClass().id() == StringFieldValue::classId); - assert(xweight.getClass().id() == IntFieldValue::classId); + assert(key.isA(FieldValue::Type::STRING)); + assert(xweight.isA(FieldValue::Type::INT)); const auto &element = static_cast<const StringFieldValue &>(key); int32_t weight = xweight.getAsInt(); startElement(weight); @@ -457,18 +456,17 @@ FieldInverter::startDoc(uint32_t docId) { void FieldInverter::invertNormalDocTextField(const FieldValue &val) { - const vespalib::Identifiable::RuntimeClass & cInfo(val.getClass()); const Schema::IndexField &field = _schema.getIndexField(_fieldId); switch (field.getCollectionType()) { case CollectionType::SINGLE: - if (cInfo.id() == StringFieldValue::classId) { + if (val.isA(FieldValue::Type::STRING)) { processNormalDocTextField(static_cast<const StringFieldValue &>(val)); } else { throw std::runtime_error(make_string("Expected DataType::STRING, got '%s'", val.getDataType()->getName().c_str())); } break; case CollectionType::WEIGHTEDSET: - if (cInfo.id() == WeightedSetFieldValue::classId) { + if (val.isA(FieldValue::Type::WSET)) { const auto &wset = static_cast<const WeightedSetFieldValue &>(val); if (wset.getNestedType() == *DataType::STRING) { processNormalDocWeightedSetTextField(wset); @@ -476,11 +474,11 @@ FieldInverter::invertNormalDocTextField(const FieldValue &val) throw std::runtime_error(make_string("Expected DataType::STRING, got '%s'", wset.getNestedType().getName().c_str())); } } else { - throw std::runtime_error(make_string("Expected weighted set, got '%s'", cInfo.name())); + throw std::runtime_error(make_string("Expected weighted set, got '%s'", val.className())); } break; case CollectionType::ARRAY: - if (cInfo.id() == ArrayFieldValue::classId) { + if (val.isA(FieldValue::Type::ARRAY)) { const auto &arr = static_cast<const ArrayFieldValue&>(val); if (arr.getNestedType() == *DataType::STRING) { processNormalDocArrayTextField(arr); @@ -488,7 +486,7 @@ FieldInverter::invertNormalDocTextField(const FieldValue &val) throw std::runtime_error(make_string("Expected DataType::STRING, got '%s'", arr.getNestedType().getName().c_str())); } } else { - throw std::runtime_error(make_string("Expected Array, got '%s'", cInfo.name())); + throw std::runtime_error(make_string("Expected Array, got '%s'", val.className())); } break; default: diff --git a/searchlib/src/vespa/searchlib/memoryindex/url_field_inverter.cpp b/searchlib/src/vespa/searchlib/memoryindex/url_field_inverter.cpp index 326b7b0967a..87bcdd31933 100644 --- a/searchlib/src/vespa/searchlib/memoryindex/url_field_inverter.cpp +++ b/searchlib/src/vespa/searchlib/memoryindex/url_field_inverter.cpp @@ -6,7 +6,6 @@ #include <vespa/document/fieldvalue/arrayfieldvalue.h> #include <vespa/document/fieldvalue/stringfieldvalue.h> #include <vespa/document/fieldvalue/weightedsetfieldvalue.h> -#include <vespa/searchlib/common/sort.h> #include <vespa/searchlib/util/url.h> #include <vespa/vespalib/text/lowercase.h> #include <vespa/vespalib/text/utf8.h> @@ -122,7 +121,7 @@ UrlFieldInverter::processUrlSubField(FieldInverter *inverter, if (!sfv) { return; } - if (!sfv->inherits(IDENTIFIABLE_CLASSID(StringFieldValue))) { + if (!sfv->isA(FieldValue::Type::STRING)) { LOG(error, "Illegal field type %s for URL subfield %s, expected string", sfv->getDataType()->getName().c_str(), @@ -155,13 +154,13 @@ UrlFieldInverter::processAnnotatedUrlField(const StructFieldValue & field) void UrlFieldInverter::processUrlField(const FieldValue &url_field) { - if (url_field.inherits(IDENTIFIABLE_CLASSID(StringFieldValue))) { + if (url_field.isA(FieldValue::Type::STRING)) { const vespalib::string &url_str = static_cast<const StringFieldValue &>(url_field).getValue(); processUrlOldStyle(url_str); return; } - assert(url_field.getClass().id() == StructFieldValue::classId); + assert(url_field.isA(FieldValue::Type::STRUCT)); const auto &field = static_cast<const StructFieldValue &>(url_field); const FieldValue::UP all_val = field.getValue("all"); @@ -173,7 +172,7 @@ UrlFieldInverter::processUrlField(const FieldValue &url_field) return; } - if (!all_val->inherits(IDENTIFIABLE_CLASSID(StringFieldValue))) { + if (!all_val->isA(FieldValue::Type::STRING)) { LOG(error, "Illegal field type %s for URL subfield all, expected string", all_val->getDataType()->getName().c_str()); @@ -275,7 +274,7 @@ UrlFieldInverter::processWeightedSetUrlField(const WeightedSetFieldValue &field) for (const auto & el : field) { const FieldValue &key = *el.first; const FieldValue &xweight = *el.second; - assert(xweight.getClass().id() == IntFieldValue::classId); + assert(xweight.isA(FieldValue::Type::INT)); int32_t weight = xweight.getAsInt(); startElement(weight); processUrlField(key); @@ -298,7 +297,6 @@ isUriType(const DataType &type) void UrlFieldInverter::invertUrlField(const FieldValue &val) { - const vespalib::Identifiable::RuntimeClass & cInfo(val.getClass()); switch (_collectionType) { case CollectionType::SINGLE: if (isUriType(*val.getDataType())) { @@ -309,30 +307,29 @@ UrlFieldInverter::invertUrlField(const FieldValue &val) throw std::runtime_error(make_string("Expected URI struct, got '%s'", val.getDataType()->getName().c_str())); } break; - case CollectionType::WEIGHTEDSET: - if (cInfo.id() == WeightedSetFieldValue::classId) { - const auto &wset = static_cast<const WeightedSetFieldValue &>(val); - if (isUriType(wset.getNestedType())) { - processWeightedSetUrlField(wset); - } else { - throw std::runtime_error(make_string("Expected wset of URI struct, got '%s'", wset.getNestedType().getName().c_str())); - } + case CollectionType::WEIGHTEDSET: { + assert(val.isA(FieldValue::Type::WSET)); + const auto &wset = static_cast<const WeightedSetFieldValue &>(val); + if (isUriType(wset.getNestedType())) { + processWeightedSetUrlField(wset); } else { - throw std::runtime_error(make_string("Expected weighted set, got '%s'", cInfo.name())); + throw std::runtime_error( + make_string("Expected wset of URI struct, got '%s'", wset.getNestedType().getName().c_str())); } break; - case CollectionType::ARRAY: - if (cInfo.id() == ArrayFieldValue::classId) { - const auto &arr = static_cast<const ArrayFieldValue&>(val); - if (isUriType(arr.getNestedType())) { - processArrayUrlField(arr); - } else { - throw std::runtime_error(make_string("Expected array of URI struct, got '%s' (%s)", arr.getNestedType().getName().c_str(), arr.getNestedType().toString(true).c_str())); - } + } + case CollectionType::ARRAY: { + assert(val.isA(FieldValue::Type::ARRAY)); + const auto &arr = static_cast<const ArrayFieldValue &>(val); + if (isUriType(arr.getNestedType())) { + processArrayUrlField(arr); } else { - throw std::runtime_error(make_string("Expected Array, got '%s'", cInfo.name())); + throw std::runtime_error( + make_string("Expected array of URI struct, got '%s' (%s)", arr.getNestedType().getName().c_str(), + arr.getNestedType().toString(true).c_str())); } break; + } default: break; } diff --git a/searchsummary/src/vespa/searchsummary/docsummary/matched_elements_filter_dfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/matched_elements_filter_dfw.cpp index 2c2ce860e39..fb53ddcc470 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/matched_elements_filter_dfw.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/matched_elements_filter_dfw.cpp @@ -82,7 +82,7 @@ filter_matching_elements_in_input_field_while_converting_to_slime(const FieldVal // Only difference is that we filter matched elements on the fly. auto converted = SummaryFieldConverter::convert_field_with_filter(false, input_field_value, matching_elems); // This should hold as we also have asserted that (type == ResType::RES_JSONSTRING); - assert(converted->getClass().inherits(LiteralFieldValueB::classId)); + assert(converted->isLiteral()); auto& literal = static_cast<const LiteralFieldValueB&>(*converted); vespalib::stringref buf = literal.getValueRef(); Slime input_field_as_slime; diff --git a/searchsummary/src/vespa/searchsummary/docsummary/summaryfieldconverter.cpp b/searchsummary/src/vespa/searchsummary/docsummary/summaryfieldconverter.cpp index 487fb9e329f..c107e5c8739 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/summaryfieldconverter.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/summaryfieldconverter.cpp @@ -29,7 +29,6 @@ #include <vespa/eval/eval/value_codec.h> #include <vespa/searchcommon/common/schema.h> #include <vespa/searchlib/util/url.h> -#include <vespa/vespalib/encoding/base64.h> #include <vespa/vespalib/geo/zcurve.h> #include <vespa/vespalib/stllike/asciistream.h> #include <vespa/vespalib/util/size_literals.h> @@ -176,7 +175,7 @@ void handleIndexingTerms(Handler &handler, const StringFieldValue &value) { const StringFieldValue &ensureStringFieldValue(const FieldValue &value) __attribute__((noinline)); const StringFieldValue &ensureStringFieldValue(const FieldValue &value) { - if (!value.inherits(IDENTIFIABLE_CLASSID(StringFieldValue))) { + if (!value.isA(FieldValue::Type::STRING)) { throw vespalib::IllegalArgumentException("Illegal field type. " + value.toString(), VESPA_STRLOC); } return static_cast<const StringFieldValue &>(value); @@ -287,9 +286,7 @@ class SummaryFieldValueConverter : protected ConstFieldValueVisitor void visit(const StructFieldValue &value) override { if (*value.getDataType() == *SearchDataType::URI) { FieldValue::UP uriAllValue = value.getValue("all"); - if (uriAllValue && - uriAllValue->inherits(IDENTIFIABLE_CLASSID(StringFieldValue))) - { + if (uriAllValue && uriAllValue->isA(FieldValue::Type::STRING)) { uriAllValue->accept(*this); return; } @@ -488,9 +485,7 @@ private: } if (*value.getDataType() == *SearchDataType::URI) { FieldValue::UP uriAllValue = value.getValue("all"); - if (uriAllValue && - uriAllValue->inherits(IDENTIFIABLE_CLASSID(StringFieldValue))) - { + if (uriAllValue && uriAllValue->isA(FieldValue::Type::STRING)) { uriAllValue->accept(*this); return; } diff --git a/staging_vespalib/src/vespa/vespalib/objects/objectvisitor.h b/staging_vespalib/src/vespa/vespalib/objects/objectvisitor.h index 7e48e9f5b4b..dba731a8940 100644 --- a/staging_vespalib/src/vespa/vespalib/objects/objectvisitor.h +++ b/staging_vespalib/src/vespa/vespalib/objects/objectvisitor.h @@ -2,7 +2,6 @@ #pragma once #include <vespa/vespalib/stllike/string.h> -#include <stdint.h> namespace vespalib { diff --git a/staging_vespalib/src/vespa/vespalib/util/xmlserializable.h b/staging_vespalib/src/vespa/vespalib/util/xmlserializable.h index 1ceee6dd7b2..76f0ad1fa3a 100644 --- a/staging_vespalib/src/vespa/vespalib/util/xmlserializable.h +++ b/staging_vespalib/src/vespa/vespalib/util/xmlserializable.h @@ -17,7 +17,7 @@ class XmlSerializable { public: XmlSerializable() {} - virtual ~XmlSerializable() {} + virtual ~XmlSerializable() = default; virtual void printXml(XmlOutputStream& out) const = 0; diff --git a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp index cbf58b5313d..1e091d9a6d8 100644 --- a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp +++ b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp @@ -72,7 +72,7 @@ createMultiValueAttribute(const vespalib::string & name, const document::FieldVa ndt = &cdt->getNestedType(); } LOG(debug, "Create %s attribute '%s' with data type '%s' (%s)", - arrayType ? "array" : "weighted set", name.c_str(), ndt->getName().c_str(), fv.getClass().name()); + arrayType ? "array" : "weighted set", name.c_str(), ndt->getName().c_str(), fv.className()); if (ndt->getId() == DataType::T_BYTE || ndt->getId() == DataType::T_INT || ndt->getId() == DataType::T_LONG) @@ -89,7 +89,7 @@ createMultiValueAttribute(const vespalib::string & name, const document::FieldVa : std::make_shared<search::WeightedSetStringExtAttribute>(name); } else { LOG(debug, "Can not make an multivalue attribute out of %s with data type '%s' (%s)", - name.c_str(), ndt->getName().c_str(), fv.getClass().name()); + name.c_str(), ndt->getName().c_str(), fv.className()); } return AttributeVector::SP(); } @@ -97,15 +97,15 @@ createMultiValueAttribute(const vespalib::string & name, const document::FieldVa AttributeVector::SP createAttribute(const vespalib::string & name, const document::FieldValue & fv) { - LOG(debug, "Create single value attribute '%s' with value type '%s'", name.c_str(), fv.getClass().name()); - if (fv.inherits(document::ByteFieldValue::classId) || fv.inherits(document::IntFieldValue::classId) || fv.inherits(document::LongFieldValue::classId)) { + LOG(debug, "Create single value attribute '%s' with value type '%s'", name.c_str(), fv.className()); + if (fv.isA(document::FieldValue::Type::BYTE) || fv.isA(document::FieldValue::Type::INT) || fv.isA(document::FieldValue::Type::LONG)) { return std::make_shared<search::SingleIntegerExtAttribute>(name); - } else if (fv.inherits(document::DoubleFieldValue::classId) || fv.inherits(document::FloatFieldValue::classId)) { + } else if (fv.isA(document::FieldValue::Type::DOUBLE) || fv.isA(document::FieldValue::Type::FLOAT)) { return std::make_shared<search::SingleFloatExtAttribute>(name); - } else if (fv.inherits(document::StringFieldValue::classId)) { + } else if (fv.isA(document::FieldValue::Type::STRING)) { return std::make_shared<search::SingleStringExtAttribute>(name); } else { - LOG(debug, "Can not make an attribute out of %s of type '%s'.", name.c_str(), fv.getClass().name()); + LOG(debug, "Can not make an attribute out of %s of type '%s'.", name.c_str(), fv.className()); } return AttributeVector::SP(); } @@ -761,14 +761,14 @@ void SearchVisitor::setupAttributeVector(const FieldPath &fieldPath) { if (attr) { LOG(debug, "Adding attribute '%s' for field '%s' with data type '%s' (%s)", - attr->getName().c_str(), attrName.c_str(), fv.getDataType()->getName().c_str(), fv.getClass().name()); + attr->getName().c_str(), attrName.c_str(), fv.getDataType()->getName().c_str(), fv.className()); if ( ! _attrMan.add(attr) ) { LOG(warning, "Failed adding attribute '%s' for field '%s' with data type '%s' (%s)", - attr->getName().c_str(), attrName.c_str(), fv.getDataType()->getName().c_str(), fv.getClass().name()); + attr->getName().c_str(), attrName.c_str(), fv.getDataType()->getName().c_str(), fv.className()); } } else { LOG(debug, "Cannot setup attribute for field '%s' with data type '%s' (%s). Aggregation and sorting will not work for this field", - attrName.c_str(), fv.getDataType()->getName().c_str(), fv.getClass().name()); + attrName.c_str(), fv.getDataType()->getName().c_str(), fv.className()); } } diff --git a/vdslib/src/vespa/vdslib/container/parameters.cpp b/vdslib/src/vespa/vdslib/container/parameters.cpp index 85ba6318f7c..60527a00547 100644 --- a/vdslib/src/vespa/vdslib/container/parameters.cpp +++ b/vdslib/src/vespa/vdslib/container/parameters.cpp @@ -2,7 +2,6 @@ #include "parameters.hpp" #include <vespa/document/util/bytebuffer.h> -#include <vespa/vespalib/objects/nbostream.h> #include <vespa/vespalib/objects/hexdump.h> #include <vespa/vespalib/stllike/hash_map.hpp> #include <vespa/vespalib/util/xmlstream.h> @@ -60,7 +59,7 @@ void Parameters::deserialize(document::ByteBuffer& buffer) } void -Parameters::printXml(document::XmlOutputStream& xos) const +Parameters::printXml(vespalib::xml::XmlOutputStream& xos) const { using namespace vespalib::xml; xos << XmlTag("parameters"); diff --git a/vdslib/src/vespa/vdslib/container/parameters.h b/vdslib/src/vespa/vdslib/container/parameters.h index 34568cc85cb..41c95d14da4 100644 --- a/vdslib/src/vespa/vdslib/container/parameters.h +++ b/vdslib/src/vespa/vdslib/container/parameters.h @@ -14,7 +14,7 @@ #pragma once -#include <vespa/document/util/xmlserializable.h> +#include <vespa/vespalib/util/xmlserializable.h> #include <vespa/vespalib/stllike/hash_map.h> namespace vespalib { class GrowableByteBuffer; } @@ -22,7 +22,7 @@ namespace document { class ByteBuffer; } namespace vdslib { -class Parameters : public document::XmlSerializable { +class Parameters : public vespalib::xml::XmlSerializable { public: typedef vespalib::stringref KeyT; class Value : public vespalib::string @@ -39,7 +39,7 @@ public: private: ParametersMap _parameters; - void printXml(document::XmlOutputStream& xos) const override; + void printXml(vespalib::xml::XmlOutputStream& xos) const override; public: Parameters(); diff --git a/vsm/src/vespa/vsm/searcher/fieldsearcher.cpp b/vsm/src/vespa/vsm/searcher/fieldsearcher.cpp index c587f9eadfb..e69999b160e 100644 --- a/vsm/src/vespa/vsm/searcher/fieldsearcher.cpp +++ b/vsm/src/vespa/vsm/searcher/fieldsearcher.cpp @@ -30,7 +30,7 @@ FieldSearcherBase::FieldSearcherBase() : _qtl(), _qtlFastBuffer(), _qtlFastSize(0), - _qtlFast(NULL) + _qtlFast(nullptr) { } @@ -38,7 +38,7 @@ FieldSearcherBase::FieldSearcherBase(const FieldSearcherBase & org) : _qtl(), _qtlFastBuffer(), _qtlFastSize(0), - _qtlFast(NULL) + _qtlFast(nullptr) { prepare(org._qtl); } @@ -260,8 +260,7 @@ bool FieldSearcher::onSearch(const StorageDocument & doc) bool retval(true); size_t fNo(field()); const StorageDocument::SubDocument & sub = doc.getComplexField(fNo); - if (sub.getFieldValue() != NULL) { - LOG(spam, "onSearch %s : %s", sub.getFieldValue()->getClass().name(), sub.getFieldValue()->toString().c_str()); + if (sub.getFieldValue() != nullptr) { IteratorHandler ih(*this); sub.getFieldValue()->iterateNested(sub.getRange(), ih); } @@ -282,10 +281,10 @@ FieldSearcher::IteratorHandler::onCollectionStart(const Content & c) { const document::FieldValue & fv = c.getValue(); LOG(spam, "onCollectionStart: field value '%s'", fv.toString().c_str()); - if (fv.inherits(document::ArrayFieldValue::classId)) { + if (fv.isA(document::FieldValue::Type::ARRAY)) { const document::ArrayFieldValue & afv = static_cast<const document::ArrayFieldValue &>(fv); LOG(spam, "onCollectionStart: Array size = '%zu'", afv.size()); - } else if (fv.inherits(document::WeightedSetFieldValue::classId)) { + } else if (fv.isA(document::FieldValue::Type::WSET)) { const document::WeightedSetFieldValue & wsfv = static_cast<const document::WeightedSetFieldValue &>(fv); LOG(spam, "onCollectionStart: WeightedSet size = '%zu'", wsfv.size()); } diff --git a/vsm/src/vespa/vsm/vsm/docsumfilter.cpp b/vsm/src/vespa/vsm/vsm/docsumfilter.cpp index a74e41dfb3f..bd16c687fc7 100644 --- a/vsm/src/vespa/vsm/vsm/docsumfilter.cpp +++ b/vsm/src/vespa/vsm/vsm/docsumfilter.cpp @@ -71,7 +71,7 @@ public: StringResultHandler(ResType t, ResultPacker & p) : _type(t), _packer(p) {} void onPrimitive(uint32_t, const Content & c) override { const document::FieldValue & fv = c.getValue(); - if (fv.getClass().inherits(document::LiteralFieldValueB::classId)) { + if (fv.isLiteral()) { const document::LiteralFieldValueB & lfv = static_cast<const document::LiteralFieldValueB &>(fv); vespalib::stringref s = lfv.getValueRef(); addToPacker(s.data(), s.size()); diff --git a/vsm/src/vespa/vsm/vsm/flattendocsumwriter.cpp b/vsm/src/vespa/vsm/vsm/flattendocsumwriter.cpp index 821434a4ed6..06b652d85e6 100644 --- a/vsm/src/vespa/vsm/vsm/flattendocsumwriter.cpp +++ b/vsm/src/vespa/vsm/vsm/flattendocsumwriter.cpp @@ -18,13 +18,12 @@ FlattenDocsumWriter::onPrimitive(uint32_t, const Content & c) { considerSeparator(); const document::FieldValue & fv = c.getValue(); - const auto & clazz = fv.getClass(); - if (clazz.inherits(document::LiteralFieldValueB::classId)) { + if (fv.isLiteral()) { const document::LiteralFieldValueB & lfv = static_cast<const document::LiteralFieldValueB &>(fv); vespalib::stringref value = lfv.getValueRef(); _output.put(value.data(), value.size()); - } else if (clazz.inherits(document::NumericFieldValueBase::classId) || - clazz.inherits(document::BoolFieldValue::classId)) + } else if (fv.isNumeric() || + fv.isA(document::FieldValue::Type::BOOL)) { vespalib::string value = fv.getAsString(); _output.put(value.data(), value.size()); diff --git a/vsm/src/vespa/vsm/vsm/slimefieldwriter.cpp b/vsm/src/vespa/vsm/vsm/slimefieldwriter.cpp index 405f2292f5d..5bc5798fb9d 100644 --- a/vsm/src/vespa/vsm/vsm/slimefieldwriter.cpp +++ b/vsm/src/vespa/vsm/vsm/slimefieldwriter.cpp @@ -48,13 +48,12 @@ namespace vsm { void SlimeFieldWriter::traverseRecursive(const document::FieldValue & fv, Inserter &inserter) { - const auto & clazz = fv.getClass(); LOG(debug, "traverseRecursive: class(%s), fieldValue(%s), currentPath(%s)", - clazz.name(), fv.toString().c_str(), toString(_currPath).c_str()); + fv.className(), fv.toString().c_str(), toString(_currPath).c_str()); - if (clazz.inherits(document::CollectionFieldValue::classId)) { + if (fv.isCollection()) { const document::CollectionFieldValue & cfv = static_cast<const document::CollectionFieldValue &>(fv); - if (cfv.inherits(document::ArrayFieldValue::classId)) { + if (cfv.isA(document::FieldValue::Type::ARRAY)) { const document::ArrayFieldValue & afv = static_cast<const document::ArrayFieldValue &>(cfv); Cursor &a = inserter.insertArray(); for (size_t i = 0; i < afv.size(); ++i) { @@ -62,7 +61,8 @@ SlimeFieldWriter::traverseRecursive(const document::FieldValue & fv, Inserter &i ArrayInserter ai(a); traverseRecursive(nfv, ai); } - } else if (cfv.inherits(document::WeightedSetFieldValue::classId)) { + } else { + assert(cfv.isA(document::FieldValue::Type::WSET)); const document::WeightedSetFieldValue & wsfv = static_cast<const document::WeightedSetFieldValue &>(cfv); Cursor &a = inserter.insertArray(); Symbol isym = a.resolve("item"); @@ -75,10 +75,8 @@ SlimeFieldWriter::traverseRecursive(const document::FieldValue & fv, Inserter &i int weight = static_cast<const document::IntFieldValue &>(*entry.second).getValue(); o.setLong(wsym, weight); } - } else { - LOG(warning, "traverseRecursive: Cannot handle collection field value of type '%s'", clazz.name()); } - } else if (clazz.inherits(document::MapFieldValue::classId)) { + } else if (fv.isA(document::FieldValue::Type::MAP)) { const document::MapFieldValue & mfv = static_cast<const document::MapFieldValue &>(fv); Cursor &a = inserter.insertArray(); Symbol keysym = a.resolve("key"); @@ -92,7 +90,7 @@ SlimeFieldWriter::traverseRecursive(const document::FieldValue & fv, Inserter &i traverseRecursive(*entry.second, vi); _currPath.pop_back(); } - } else if (clazz.inherits(document::StructuredFieldValue::classId)) { + } else if (fv.isStructured()) { const document::StructuredFieldValue & sfv = static_cast<const document::StructuredFieldValue &>(fv); Cursor &o = inserter.insertObject(); if (sfv.getDataType() == &document::PositionDataType::getInstance() @@ -135,10 +133,10 @@ SlimeFieldWriter::traverseRecursive(const document::FieldValue & fv, Inserter &i } } } else { - if (clazz.inherits(document::LiteralFieldValueB::classId)) { + if (fv.isLiteral()) { const document::LiteralFieldValueB & lfv = static_cast<const document::LiteralFieldValueB &>(fv); inserter.insertString(lfv.getValueRef()); - } else if (clazz.inherits(document::NumericFieldValueBase::classId)) { + } else if (fv.isNumeric()) { switch (fv.getDataType()->getId()) { case document::DataType::T_BYTE: case document::DataType::T_SHORT: @@ -155,7 +153,7 @@ SlimeFieldWriter::traverseRecursive(const document::FieldValue & fv, Inserter &i default: inserter.insertString(fv.getAsString()); } - } else if (clazz.inherits(document::BoolFieldValue::classId)) { + } else if (fv.isA(document::FieldValue::Type::BOOL)) { const auto & bfv = static_cast<const document::BoolFieldValue &>(fv); inserter.insertBool(bfv.getValue()); } else { |