diff options
Diffstat (limited to 'document')
38 files changed, 234 insertions, 466 deletions
diff --git a/document/src/main/java/com/yahoo/document/DataType.java b/document/src/main/java/com/yahoo/document/DataType.java index bb1777954a3..697536a8ac0 100644 --- a/document/src/main/java/com/yahoo/document/DataType.java +++ b/document/src/main/java/com/yahoo/document/DataType.java @@ -52,6 +52,7 @@ public abstract class DataType extends Identifiable implements Serializable, Com public final static DocumentType DOCUMENT = new DocumentType("document"); public final static PrimitiveDataType URI = new PrimitiveDataType("uri", 10, UriFieldValue.class, new UriFieldValue.Factory()); public final static NumericDataType BYTE = new NumericDataType("byte", 16, ByteFieldValue.class, ByteFieldValue.getFactory()); + final static int TAG_ID = 18; public final static PrimitiveDataType PREDICATE = new PrimitiveDataType("predicate", 20, PredicateFieldValue.class, PredicateFieldValue.getFactory()); public final static int tensorDataTypeCode = 21; // All TensorDataType instances have id=21 but carries additional type information serialized separately // ADDITIONAL parametrized types added at runtime: map, struct, array, weighted set, annotation reference, tensor diff --git a/document/src/main/java/com/yahoo/document/DocumentTypeManagerConfigurer.java b/document/src/main/java/com/yahoo/document/DocumentTypeManagerConfigurer.java index be2c182426e..9325e374daa 100644 --- a/document/src/main/java/com/yahoo/document/DocumentTypeManagerConfigurer.java +++ b/document/src/main/java/com/yahoo/document/DocumentTypeManagerConfigurer.java @@ -61,8 +61,13 @@ public class DocumentTypeManagerConfigurer implements ConfigSubscriber.SingleSub public ConfigSubscriber configure(String configId) { ConfigSubscriber subscriber = new ConfigSubscriber(); - subscriber.subscribe(this, DocumentmanagerConfig.class, configId); - return subscriber; + try { + subscriber.subscribe(this, DocumentmanagerConfig.class, configId); + return subscriber; + } catch (RuntimeException e) { + subscriber.close(); + throw e; + } } /** One-shot configuration; should be called on a newly constructed manager */ @@ -264,7 +269,7 @@ public class DocumentTypeManagerConfigurer implements ConfigSubscriber.SingleSub var old = configMap.put(id, dataTypeConfig); if (old != null) { throw new IllegalArgumentException - ("Multiple configs for id "+id+" first: "+old+" second: "+dataTypeConfig); + ("Multiple configs for id "+id+" first:\n"+old+"\nsecond:\n"+dataTypeConfig); } } } diff --git a/document/src/main/java/com/yahoo/document/WeightedSetDataType.java b/document/src/main/java/com/yahoo/document/WeightedSetDataType.java index 35dd13efb0b..b21f059bd7d 100644 --- a/document/src/main/java/com/yahoo/document/WeightedSetDataType.java +++ b/document/src/main/java/com/yahoo/document/WeightedSetDataType.java @@ -24,25 +24,33 @@ public class WeightedSetDataType extends CollectionDataType { public WeightedSetDataType(DataType nestedType, boolean createIfNonExistent, boolean removeIfZero) { this(nestedType, createIfNonExistent, removeIfZero, 0); - if ((nestedType == STRING) && createIfNonExistent && removeIfZero) { // the tag type definition - setId(18); - } else { - setId(getName().toLowerCase().hashCode()); - } } public WeightedSetDataType(DataType nestedType, boolean createIfNonExistent, boolean removeIfZero, int id) { super(createName(nestedType, createIfNonExistent, removeIfZero), id, nestedType); this.createIfNonExistent = createIfNonExistent; this.removeIfZero = removeIfZero; + if (id == 0) { + if ((nestedType == STRING) && createIfNonExistent && removeIfZero) { // the tag type definition + setId(TAG_ID); + } else { + setId(getName().toLowerCase().hashCode()); + } + } + int code = getId(); + if ((code >= 0) && (code <= DataType.lastPredefinedDataTypeId()) && (code != TAG_ID)) { + throw new IllegalArgumentException("Cannot create a weighted set datatype with code " + code); + } } + /* + * @deprecated // TODO remove on Vespa 8 + * Do not use - use one of the constructors above. + * Note: ignores typeName argument. + */ + @Deprecated public WeightedSetDataType(String typeName, int code, DataType nestedType, boolean createIfNonExistent, boolean removeIfZero) { - super(typeName != null ? createName(nestedType, createIfNonExistent, removeIfZero) : null, code, nestedType); - if ((code >= 0) && (code <= DataType.lastPredefinedDataTypeId()) && (code != 18)) // 18 == DataType.TAG.getId() is not yet initialized - throw new IllegalArgumentException("Cannot create a weighted set datatype with code " + code); - this.createIfNonExistent = createIfNonExistent; - this.removeIfZero = removeIfZero; + this(nestedType, createIfNonExistent, removeIfZero, code); } @Override diff --git a/document/src/tests/arrayfieldvaluetest.cpp b/document/src/tests/arrayfieldvaluetest.cpp index a8ca9d22916..375ce05a4e6 100644 --- a/document/src/tests/arrayfieldvaluetest.cpp +++ b/document/src/tests/arrayfieldvaluetest.cpp @@ -3,7 +3,6 @@ #include <vespa/document/fieldvalue/fieldvalues.h> #include <vespa/document/serialization/vespadocumentdeserializer.h> #include <vespa/vespalib/objects/nbostream.h> -#include <vespa/document/util/bytebuffer.h> #include <vespa/document/repo/documenttyperepo.h> #include <gtest/gtest.h> #include <gmock/gmock.h> @@ -103,21 +102,14 @@ TEST(ArrayFieldValueTest, testArray) ArrayFieldValue::UP valuePtr(value2.clone()); EXPECT_EQ(value, *valuePtr); - // Iterating + // Iterating const ArrayFieldValue& constVal(value); - for(ArrayFieldValue::const_iterator it = constVal.begin(); - it != constVal.end(); ++it) - { - const FieldValue& fval1(*it); - (void) fval1; - EXPECT_EQ((uint32_t) IntFieldValue::classId, - it->getClass().id()); + for(const FieldValue & fval1 : constVal) { + EXPECT_EQ((uint32_t) IntFieldValue::classId, fval1.getClass().id()); } value2 = value; - for(ArrayFieldValue::iterator it = value2.begin(); it != value2.end(); ++it) - { - (*it).assign(IntFieldValue(7)); - it->assign(IntFieldValue(7)); + for(size_t i(0); i < value2.size(); i++) { + value2[i].assign(IntFieldValue(7)); } EXPECT_TRUE(value != value2); EXPECT_TRUE(value2.contains(IntFieldValue(7))); diff --git a/document/src/tests/documentselectparsertest.cpp b/document/src/tests/documentselectparsertest.cpp index f40aec41e16..d2fa969daa9 100644 --- a/document/src/tests/documentselectparsertest.cpp +++ b/document/src/tests/documentselectparsertest.cpp @@ -1,5 +1,6 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include <vespa/document/test/fieldvalue_helpers.h> #include <vespa/document/repo/configbuilder.h> #include <vespa/document/repo/documenttyperepo.h> #include <vespa/document/update/assignvalueupdate.h> @@ -152,18 +153,18 @@ DocumentSelectParserTest::createDocs() // Add some arrays and structs to doc 1 { StructFieldValue sval(_doc.back()->getField("mystruct").getDataType()); - sval.set("key", 14); - sval.set("value", "structval"); + sval.setValue("key", IntFieldValue::make(14)); + sval.setValue("value", StringFieldValue::make("structval")); _doc.back()->setValue("mystruct", sval); ArrayFieldValue aval(_doc.back()->getField("structarray").getDataType()); { StructFieldValue sval1(aval.getNestedType()); - sval1.set("key", 15); - sval1.set("value", "structval1"); + sval1.setValue("key", IntFieldValue::make(15)); + sval1.setValue("value", StringFieldValue::make("structval1")); StructFieldValue sval2(aval.getNestedType()); - sval2.set("key", 16); - sval2.set("value", "structval2"); + sval2.setValue("key", IntFieldValue::make(16)); + sval2.setValue("value", StringFieldValue::make("structval2")); aval.add(sval1); aval.add(sval2); } @@ -181,11 +182,11 @@ DocumentSelectParserTest::createDocs() ArrayFieldValue abval(_doc.back()->getField("structarray").getDataType()); { StructFieldValue sval1(aval.getNestedType()); - sval1.set("key", 17); - sval1.set("value", "structval3"); + sval1.setValue("key", IntFieldValue::make(17)); + sval1.setValue("value", StringFieldValue::make("structval3")); StructFieldValue sval2(aval.getNestedType()); - sval2.set("key", 18); - sval2.set("value", "structval4"); + sval2.setValue("key", IntFieldValue::make(18)); + sval2.setValue("value", StringFieldValue::make("structval4")); abval.add(sval1); abval.add(sval2); } @@ -193,17 +194,15 @@ DocumentSelectParserTest::createDocs() amval.put(StringFieldValue("bar"), abval); _doc.back()->setValue("structarrmap", amval); - WeightedSetFieldValue wsval( - _doc.back()->getField("stringweightedset").getDataType()); - wsval.add("foo"); - wsval.add("val1"); - wsval.add("val2"); - wsval.add("val3"); - wsval.add("val4"); + WeightedSetFieldValue wsval(_doc.back()->getField("stringweightedset").getDataType()); + WSetHelper(wsval).add("foo"); + WSetHelper(wsval).add("val1"); + WSetHelper(wsval).add("val2"); + WSetHelper(wsval).add("val3"); + WSetHelper(wsval).add("val4"); _doc.back()->setValue("stringweightedset", wsval); - WeightedSetFieldValue wsbytes( - _doc.back()->getField("byteweightedset").getDataType()); + WeightedSetFieldValue wsbytes(_doc.back()->getField("byteweightedset").getDataType()); wsbytes.add(ByteFieldValue(5)); wsbytes.add(ByteFieldValue(75)); wsbytes.add(ByteFieldValue(static_cast<int8_t>(255))); @@ -211,14 +210,12 @@ DocumentSelectParserTest::createDocs() _doc.back()->setValue("byteweightedset", wsbytes); } - _doc.push_back(createDoc( - "testdoctype1", "id:myspace:testdoctype1:n=1234:footype1", 15, 1.0, "some", "some", 0)); // DOC 2 + _doc.push_back(createDoc("testdoctype1", "id:myspace:testdoctype1:n=1234:footype1", 15, 1.0, "some", "some", 0)); // DOC 2 // Add empty struct and array { StructFieldValue sval(_doc.back()->getField("mystruct").getDataType()); _doc.back()->setValue("mystruct", sval); - ArrayFieldValue aval( - _doc.back()->getField("structarray").getDataType()); + ArrayFieldValue aval(_doc.back()->getField("structarray").getDataType()); _doc.back()->setValue("structarray", aval); } _doc.push_back(createDoc("testdoctype1", "id:myspace:testdoctype1:g=yahoo:bar", 14, 2.4, "Yet", "\xE4\xB8\xBA\xE4\xBB\x80", 0)); // DOC 3 diff --git a/document/src/tests/documenttestcase.cpp b/document/src/tests/documenttestcase.cpp index fde702f2080..c852e219faa 100644 --- a/document/src/tests/documenttestcase.cpp +++ b/document/src/tests/documenttestcase.cpp @@ -1,5 +1,6 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include <vespa/document/test/fieldvalue_helpers.h> #include <vespa/document/base/testdocman.h> #include <vespa/document/datatype/documenttype.h> #include <vespa/document/datatype/mapdatatype.h> @@ -349,11 +350,12 @@ TEST(DocumentTest, testModifyDocument) structmap1.put(StringFieldValue("test"), l2s1); l1s1.setValue(structmapF, structmap1); - WeightedSetFieldValue wset1(wset); + WeightedSetFieldValue wwset1(wset); + WSetHelper wset1(wwset1); wset1.add("foo"); wset1.add("bar"); wset1.add("zoo"); - l1s1.setValue(wsetF, wset1); + l1s1.setValue(wsetF, wwset1); WeightedSetFieldValue wset2(structwset); wset2.add(l2s1); @@ -705,19 +707,19 @@ TEST(DocumentTest,testReadSerializedAllVersions) // Create a memory instance of document { Document doc(*docType, DocumentId("id:ns:serializetest::http://test.doc.id/")); - doc.set("intfield", 5); - doc.set("floatfield", -9.23); - doc.set("stringfield", "This is a string."); - doc.set("longfield", static_cast<int64_t>(398420092938472983LL)); - doc.set("doublefield", 98374532.398820); - doc.set("bytefield", -2); - doc.setValue("rawfield", RawFieldValue("RAW DATA", 8)); + doc.setValue("intfield", IntFieldValue::make(5)); + doc.setValue("floatfield", FloatFieldValue::make(-9.23)); + doc.setValue("stringfield", StringFieldValue::make("This is a string.")); + doc.setValue("longfield", LongFieldValue::make(static_cast<int64_t>(398420092938472983LL))); + doc.setValue("doublefield", DoubleFieldValue::make(98374532.398820)); + doc.setValue("bytefield", ByteFieldValue::make(-2)); + doc.setValue("rawfield", std::make_unique<RawFieldValue>("RAW DATA", 8)); Document docInDoc(*docInDocType, DocumentId("id:ns:docindoc::http://doc.in.doc/")); - docInDoc.set("stringindocfield", "Elvis is dead"); + docInDoc.setValue("stringindocfield", StringFieldValue::make("Elvis is dead")); doc.setValue("docfield", docInDoc); ArrayFieldValue floatArray(*arrayOfFloatDataType); - floatArray.add(1.0); - floatArray.add(2.0); + CollectionHelper(floatArray).add(1.0); + CollectionHelper(floatArray).add(2.0); doc.setValue("arrayoffloatfield", floatArray); WeightedSetFieldValue weightedSet(*weightedSetDataType); weightedSet.add(StringFieldValue("Weighted 0"), 50); @@ -828,14 +830,14 @@ TEST(DocumentTest, testGenerateSerializedFile) DocumentTypeRepo repo(readDocumenttypesConfig(file_name)); Document doc(*repo.getDocumentType("serializetest"), DocumentId("id:ns:serializetest::http://test.doc.id/")); - doc.set("intfield", 5); - doc.set("floatfield", -9.23); - doc.set("stringfield", "This is a string."); - doc.set("longfield", (int64_t) 398420092938472983ll); - doc.set("doublefield", 98374532.398820); - doc.set("urifield", "http://this.is.a.test/"); - doc.set("bytefield", -2); - doc.set("rawfield", "RAW DATA"); + doc.setValue("intfield", IntFieldValue::make(5)); + doc.setValue("floatfield", FloatFieldValue::make(-9.23)); + doc.setValue("stringfield", StringFieldValue::make("This is a string.")); + doc.setValue("longfield", LongFieldValue::make((int64_t) 398420092938472983ll)); + doc.setValue("doublefield", DoubleFieldValue::make(98374532.398820)); + doc.setValue("urifield", StringFieldValue::make("http://this.is.a.test/")); + doc.setValue("bytefield", ByteFieldValue::make(-2)); + doc.setValue("rawfield", std::make_unique<RawFieldValue>("RAW DATA")); const DocumentType *docindoc_type = repo.getDocumentType("docindoc"); EXPECT_TRUE(docindoc_type); @@ -949,7 +951,7 @@ TEST(DocumentTest, testHasChanged) Document doc2(test_repo.getTypeRepo(), buf); EXPECT_TRUE(!doc2.hasChanged()); - doc2.set("headerval", 13); + doc2.setValue("headerval", IntFieldValue::make(13)); EXPECT_TRUE(doc2.hasChanged()); } // Overwriting a value in doc tags us changed. @@ -957,7 +959,7 @@ TEST(DocumentTest, testHasChanged) buf.rp(0); Document doc2(test_repo.getTypeRepo(), buf); - doc2.set("hstringval", "bla bla bla bla bla"); + doc2.setValue("hstringval", StringFieldValue::make("bla bla bla bla bla")); EXPECT_TRUE(doc2.hasChanged()); } // Clearing value tags us changed. diff --git a/document/src/tests/documentupdatetestcase.cpp b/document/src/tests/documentupdatetestcase.cpp index 8a9aef0bde4..26819699db4 100644 --- a/document/src/tests/documentupdatetestcase.cpp +++ b/document/src/tests/documentupdatetestcase.cpp @@ -1,5 +1,6 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include <vespa/document/test/fieldvalue_helpers.h> #include <vespa/document/base/testdocman.h> #include <vespa/document/base/exceptions.h> #include <vespa/document/datatype/tensor_data_type.h> @@ -138,8 +139,8 @@ TEST(DocumentUpdateTest, testSimpleUsage) // Create a test document Document doc(*docType, DocumentId("id:ns:test::1")); - doc.set("bytef", 0); - doc.set("intf", 5); + doc.setValue("bytef", ByteFieldValue::make(0)); + doc.setValue("intf", IntFieldValue::make(5)); ArrayFieldValue array(*arrayType); array.add(IntFieldValue(3)); array.add(IntFieldValue(7)); @@ -1287,9 +1288,9 @@ TEST(DocumentUpdateTest, array_element_update_applies_to_specified_element) ArrayUpdateFixture f; ArrayFieldValue array_value(f.array_field.getDataType()); - array_value.add("foo"); - array_value.add("baz"); - array_value.add("blarg"); + CollectionHelper(array_value).add("foo"); + CollectionHelper(array_value).add("baz"); + CollectionHelper(array_value).add("blarg"); f.doc->setValue(f.array_field, array_value); f.update->applyTo(*f.doc); @@ -1306,7 +1307,7 @@ TEST(DocumentUpdateTest, array_element_update_for_invalid_index_is_ignored) ArrayUpdateFixture f; ArrayFieldValue array_value(f.array_field.getDataType()); - array_value.add("jerry"); + CollectionHelper(array_value).add("jerry"); f.doc->setValue(f.array_field, array_value); f.update->applyTo(*f.doc); // MapValueUpdate for index 1, which does not exist diff --git a/document/src/tests/fieldpathupdatetestcase.cpp b/document/src/tests/fieldpathupdatetestcase.cpp index 3ebf3699763..3d41a5bcacd 100644 --- a/document/src/tests/fieldpathupdatetestcase.cpp +++ b/document/src/tests/fieldpathupdatetestcase.cpp @@ -1,4 +1,6 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/document/test/fieldvalue_helpers.h> #include <vespa/document/base/testdocman.h> #include <vespa/document/fieldvalue/iteratorhandler.h> #include <vespa/document/fieldvalue/intfieldvalue.h> @@ -128,11 +130,12 @@ createTestDocument(const DocumentTypeRepo &repo) structmap1.put(StringFieldValue("test"), l2s1); l1s1.setValue("structmap", structmap1); - WeightedSetFieldValue wset1(*wset); + WeightedSetFieldValue wwset1(*wset); + WSetHelper wset1(wwset1); wset1.add("foo"); wset1.add("bar"); wset1.add("zoo"); - l1s1.setValue("wset", wset1); + l1s1.setValue("wset", wwset1); WeightedSetFieldValue wset2(*structwset); wset2.add(l2s1); diff --git a/document/src/tests/fieldvalue/fieldvalue_test.cpp b/document/src/tests/fieldvalue/fieldvalue_test.cpp index b70fd0d18a8..d8712768000 100644 --- a/document/src/tests/fieldvalue/fieldvalue_test.cpp +++ b/document/src/tests/fieldvalue/fieldvalue_test.cpp @@ -1,15 +1,15 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. // Unit tests for fieldvalue. -#include <vespa/log/log.h> -LOG_SETUP("fieldvalue_test"); - #include <vespa/document/fieldvalue/stringfieldvalue.h> #include <vespa/document/fieldvalue/longfieldvalue.h> #include <vespa/document/fieldvalue/intfieldvalue.h> #include <vespa/vespalib/testkit/testapp.h> +#include <vespa/log/log.h> +LOG_SETUP("fieldvalue_test"); + using namespace document; namespace { @@ -18,14 +18,6 @@ TEST("require that StringFieldValue can be assigned primitives") { StringFieldValue val; val = "foo"; EXPECT_EQUAL("foo", val.getValue()); - val = 1; - EXPECT_EQUAL("1", val.getValue()); - val = static_cast<int64_t>(2); - EXPECT_EQUAL("2", val.getValue()); - val = 3.0f; - EXPECT_EQUAL("3", val.getValue()); - val = 4.0; - EXPECT_EQUAL("4", val.getValue()); } TEST("require that FieldValues does not change their storage size.") { diff --git a/document/src/tests/primitivefieldvaluetest.cpp b/document/src/tests/primitivefieldvaluetest.cpp index 7c734544f27..ea78baa4ee6 100644 --- a/document/src/tests/primitivefieldvaluetest.cpp +++ b/document/src/tests/primitivefieldvaluetest.cpp @@ -3,7 +3,6 @@ #include <vespa/document/fieldvalue/fieldvalues.h> #include <vespa/document/serialization/vespadocumentdeserializer.h> #include <vespa/vespalib/objects/nbostream.h> -#include <vespa/document/util/bytebuffer.h> #include <vespa/document/repo/documenttyperepo.h> #include <limits> #include <gtest/gtest.h> @@ -32,7 +31,7 @@ void deserialize(nbostream & stream, T &value) { const Type& medium2, const Type& largest) { try{ - // Less + // Less EXPECT_TRUE(!(smallest < smallest)); EXPECT_TRUE(smallest < medium1); EXPECT_TRUE(smallest < medium2); @@ -203,31 +202,6 @@ TEST(PrimitiveFieldValueTest, testRaw) value.getValueRef().size()) == 0); } -#define ASSERT_FAILED_CONV(getter, totype, floating) \ -{ \ - totype toType; \ - FieldValue::UP copy(value.clone()); \ - try{ \ - getter; \ - std::ostringstream ost; \ - ost << "Conversion unexpectedly worked from max value of " \ - << *value.getDataType() << " to " << *toType.getDataType(); \ - FAIL() << ost.str(); \ - } catch (std::exception& e) { \ - EXPECT_EQ( \ - std::string("bad numeric conversion: positive overflow"), \ - std::string(e.what())); \ - } \ - /* Verify that we can convert to smaller type if value is within \ - range. Only tests integer to integer. No floating point. */ \ - if (!floating) { \ - totype::Number maxV = std::numeric_limits<totype::Number>::max(); \ - value.setValue((Number) maxV); \ - getter; \ - } \ - value.assign(*copy); \ -} - namespace { template<typename Numeric> @@ -258,25 +232,21 @@ namespace { // representation can keep the value. if (floatingPoint || sizeof(Number) > sizeof(unsigned char)) { // No longer throws. This is guarded on the perimeter by java code. - // ASSERT_FAILED_CONV(value.getAsByte(), ByteFieldValue, floatingPoint); } else { EXPECT_EQ((char) maxValue, value.getAsByte()); } if (floatingPoint || sizeof(Number) > sizeof(int32_t)) { // No longer throws. This is guarded on the perimeter by java code. - // ASSERT_FAILED_CONV(value.getAsInt(), IntFieldValue, floatingPoint); } else { EXPECT_EQ((int32_t) maxValue, value.getAsInt()); } if (floatingPoint || sizeof(Number) > sizeof(int64_t)) { // No longer throws. This is guarded on the perimeter by java code. - // ASSERT_FAILED_CONV(value.getAsLong(), LongFieldValue, floatingPoint); } else { EXPECT_EQ((int64_t) maxValue, value.getAsLong()); } if (floatingPoint && sizeof(Number) > sizeof(float)) { // No longer throws. This is guarded on the perimeter by java code. - // ASSERT_FAILED_CONV(value.getAsFloat(), FloatFieldValue, true); } else { EXPECT_EQ((float) maxValue, value.getAsFloat()); } @@ -303,30 +273,15 @@ TEST(PrimitiveFieldValueTest, testBool) v = BoolFieldValue(true); EXPECT_TRUE(v.getValue()); - v = 0; - EXPECT_TRUE( ! v.getValue()); - v = 1; - EXPECT_TRUE(v.getValue()); - - v = INT64_C(0); - EXPECT_TRUE( ! v.getValue()); - v = INT64_C(1); - EXPECT_TRUE(v.getValue()); - - v = 0.0f; - EXPECT_TRUE( ! v.getValue()); - v = 1.0f; - EXPECT_TRUE(v.getValue()); - - v = 0.0; - EXPECT_TRUE( ! v.getValue()); - v = 1.0; + v.setValue(false); + EXPECT_FALSE(v.getValue()); + v.setValue(true); EXPECT_TRUE(v.getValue()); v = vespalib::stringref("true"); EXPECT_TRUE(v.getValue()); v = vespalib::stringref("something not true"); - EXPECT_TRUE( ! v.getValue()); + EXPECT_FALSE(v.getValue()); } TEST(PrimitiveFieldValueTest, testNumerics) diff --git a/document/src/tests/serialization/vespadocumentserializer_test.cpp b/document/src/tests/serialization/vespadocumentserializer_test.cpp index d85d5240b64..33e8c521e09 100644 --- a/document/src/tests/serialization/vespadocumentserializer_test.cpp +++ b/document/src/tests/serialization/vespadocumentserializer_test.cpp @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. // Unit tests for vespadocumentserializer. +#include <vespa/document/test/fieldvalue_helpers.h> #include <vespa/document/annotation/annotation.h> #include <vespa/document/annotation/span.h> #include <vespa/document/annotation/spantree.h> @@ -345,7 +346,7 @@ void checkArrayFieldValue(SizeType value_count) { ArrayDataType array_type(*DataType::INT); ArrayFieldValue value(array_type); for (uint32_t i = 0; i < value_count; ++i) { - value.add(static_cast<int32_t>(i)); + CollectionHelper(value).add(static_cast<int32_t>(i)); } nbostream stream; diff --git a/document/src/tests/weightedsetfieldvaluetest.cpp b/document/src/tests/weightedsetfieldvaluetest.cpp index 325267e9da6..61f727120d1 100644 --- a/document/src/tests/weightedsetfieldvaluetest.cpp +++ b/document/src/tests/weightedsetfieldvaluetest.cpp @@ -1,5 +1,6 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include <vespa/document/test/fieldvalue_helpers.h> #include <vespa/document/fieldvalue/weightedsetfieldvalue.h> #include <vespa/document/fieldvalue/arrayfieldvalue.h> #include <vespa/document/fieldvalue/longfieldvalue.h> @@ -255,7 +256,8 @@ TEST(WeightedSetFieldValueTest, testWeightedSet) WeightedSetDataType mytype2(*DataType::STRING, true, true); EXPECT_EQ(*DataType::TAG, static_cast<DataType &>(mytype2)); - WeightedSetFieldValue val1(mytype1); + WeightedSetFieldValue wsval1(mytype1); + WSetHelper val1(wsval1); val1.add("foo", 4); try{ val1.increment("bar", 2); @@ -272,25 +274,26 @@ TEST(WeightedSetFieldValueTest, testWeightedSet) val1.decrement("foo", 3); EXPECT_EQ(7, val1.get("foo")); val1.decrement("foo", 7); - EXPECT_TRUE(val1.contains("foo")); + EXPECT_TRUE(CollectionHelper(wsval1).contains("foo")); - WeightedSetFieldValue val2(mytype2); + WeightedSetFieldValue wsval2(mytype2); + WSetHelper val2(wsval2); val2.add("foo", 4); val2.increment("bar", 2); EXPECT_EQ(2, val2.get("bar")); val2.decrement("bar", 4); EXPECT_EQ(-2, val2.get("bar")); val2.increment("bar", 2); - EXPECT_TRUE(!val2.contains("bar")); + EXPECT_TRUE(!CollectionHelper(wsval2).contains("bar")); val2.decrement("foo", 4); - EXPECT_TRUE(!val2.contains("foo")); + EXPECT_TRUE(!CollectionHelper(wsval2).contains("foo")); val2.decrement("foo", 4); EXPECT_EQ(-4, val2.get("foo")); val2.add("foo", 0); - EXPECT_TRUE(!val2.contains("foo")); + EXPECT_TRUE(!CollectionHelper(wsval2).contains("foo")); } } @@ -301,12 +304,12 @@ TEST(WeightedSetFieldValueTest, testAddIgnoreZeroWeight) WeightedSetFieldValue ws(wsetType); ws.addIgnoreZeroWeight(StringFieldValue("yarn"), 0); - EXPECT_TRUE(ws.contains("yarn")); - EXPECT_EQ(0, ws.get("yarn")); + EXPECT_TRUE(CollectionHelper(ws).contains("yarn")); + EXPECT_EQ(0, WSetHelper(ws).get("yarn")); ws.addIgnoreZeroWeight(StringFieldValue("flarn"), 1); - EXPECT_TRUE(ws.contains("flarn")); - EXPECT_EQ(1, ws.get("flarn")); + EXPECT_TRUE(CollectionHelper(ws).contains("flarn")); + EXPECT_EQ(1, WSetHelper(ws).get("flarn")); } } // document diff --git a/document/src/vespa/document/datatype/primitivedatatype.cpp b/document/src/vespa/document/datatype/primitivedatatype.cpp index 08e873c7de2..d5af0ca6885 100644 --- a/document/src/vespa/document/datatype/primitivedatatype.cpp +++ b/document/src/vespa/document/datatype/primitivedatatype.cpp @@ -56,16 +56,16 @@ FieldValue::UP PrimitiveDataType::createFieldValue() const { switch (getId()) { - case T_INT: return std::make_unique<IntFieldValue>(); - case T_SHORT: return std::make_unique<ShortFieldValue>(); - case T_FLOAT: return std::make_unique<FloatFieldValue>(); - case T_URI: return std::make_unique<StringFieldValue>(); - case T_STRING: return std::make_unique<StringFieldValue>(); + case T_INT: return IntFieldValue::make(); + case T_SHORT: return ShortFieldValue::make(); + case T_FLOAT: return FloatFieldValue::make(); + case T_URI: return StringFieldValue::make(); + case T_STRING: return StringFieldValue::make(); case T_RAW: return std::make_unique<RawFieldValue>(); - case T_LONG: return std::make_unique<LongFieldValue>(); - case T_DOUBLE: return std::make_unique<DoubleFieldValue>(); - case T_BOOL: return std::make_unique<BoolFieldValue>(); - case T_BYTE: return std::make_unique<ByteFieldValue>(); + case T_LONG: return LongFieldValue::make(); + case T_DOUBLE: return DoubleFieldValue::make(); + case T_BOOL: return BoolFieldValue::make(); + case T_BYTE: return ByteFieldValue::make(); case T_PREDICATE: return std::make_unique<PredicateFieldValue>(); } LOG_ABORT("getId() returned value out of range"); diff --git a/document/src/vespa/document/fieldvalue/arrayfieldvalue.h b/document/src/vespa/document/fieldvalue/arrayfieldvalue.h index b37049f207a..c4f879f7348 100644 --- a/document/src/vespa/document/fieldvalue/arrayfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/arrayfieldvalue.h @@ -74,11 +74,11 @@ public: // Iterator functionality const_iterator begin() const { return array().begin(); } const_iterator end() const { return array().end(); } - iterator begin() { return array().begin(); } - iterator end() { return array().end(); } DECLARE_IDENTIFIABLE_ABSTRACT(ArrayFieldValue); private: + iterator begin() { return array().begin(); } + iterator end() { return array().end(); } const IArray & array() const { return *_array; } IArray & array() { return *_array; } }; diff --git a/document/src/vespa/document/fieldvalue/boolfieldvalue.cpp b/document/src/vespa/document/fieldvalue/boolfieldvalue.cpp index c542936825d..1c5261877fd 100644 --- a/document/src/vespa/document/fieldvalue/boolfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/boolfieldvalue.cpp @@ -87,25 +87,5 @@ BoolFieldValue::operator=(vespalib::stringref v) { _value = (v == "true"); return *this; } -BoolFieldValue& -BoolFieldValue::operator=(int32_t v) { - _value = (v != 0); - return *this; -} -BoolFieldValue& -BoolFieldValue::operator=(int64_t v) { - _value = (v != 0); - return *this; -} -BoolFieldValue& -BoolFieldValue::operator=(float v) { - _value = (v != 0); - return *this; -} -BoolFieldValue& -BoolFieldValue::operator=(double v) { - _value = (v != 0); - return *this; -} } // namespace document diff --git a/document/src/vespa/document/fieldvalue/boolfieldvalue.h b/document/src/vespa/document/fieldvalue/boolfieldvalue.h index d03ded5c9f1..01cfcf2cd48 100644 --- a/document/src/vespa/document/fieldvalue/boolfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/boolfieldvalue.h @@ -42,12 +42,8 @@ public: vespalib::string getAsString() const override; BoolFieldValue& operator=(vespalib::stringref) override; - BoolFieldValue& operator=(int32_t) override; - BoolFieldValue& operator=(int64_t) override; - BoolFieldValue& operator=(float) override; - BoolFieldValue& operator=(double) 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.h b/document/src/vespa/document/fieldvalue/bytefieldvalue.h index 7f6bc429b69..2cccf483c84 100644 --- a/document/src/vespa/document/fieldvalue/bytefieldvalue.h +++ b/document/src/vespa/document/fieldvalue/bytefieldvalue.h @@ -14,7 +14,6 @@ namespace document { class ByteFieldValue : public NumericFieldValue<int8_t> { public: - typedef std::unique_ptr<ByteFieldValue> UP; typedef int8_t Number; ByteFieldValue(Number value = 0) @@ -24,10 +23,10 @@ public: void accept(ConstFieldValueVisitor &visitor) const override { visitor.visit(*this); } const DataType *getDataType() const override { return DataType::BYTE; } ByteFieldValue* clone() const override { return new ByteFieldValue(*this); } - using NumericFieldValue<Number>::operator=; + using NumericFieldValue<Number>::operator=; DECLARE_IDENTIFIABLE(ByteFieldValue); - + static std::unique_ptr<ByteFieldValue> make(Number value=0) { return std::make_unique<ByteFieldValue>(value); } }; } // document diff --git a/document/src/vespa/document/fieldvalue/collectionfieldvalue.h b/document/src/vespa/document/fieldvalue/collectionfieldvalue.h index fcdd7d72ebd..9efd3b91bc6 100644 --- a/document/src/vespa/document/fieldvalue/collectionfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/collectionfieldvalue.h @@ -62,41 +62,6 @@ public: virtual size_t size() const = 0; virtual void clear() = 0; - // Convenience functions for using primitives directly - - bool add(vespalib::stringref val) - { return addValue(*createNested() = val); } - bool add(int32_t val) - { return addValue(*createNested() = val); } - bool add(int64_t val) - { return addValue(*createNested() = val); } - bool add(float val) - { return addValue(*createNested() = val); } - bool add(double val) - { return addValue(*createNested() = val); } - - bool contains(vespalib::stringref val) - { return containsValue(*createNested() = val); } - bool contains(int32_t val) - { return containsValue(*createNested() = val); } - bool contains(int64_t val) - { return containsValue(*createNested() = val); } - bool contains(float val) - { return containsValue(*createNested() = val); } - bool contains(double val) - { return containsValue(*createNested() = val); } - - bool remove(vespalib::stringref val) - { return removeValue(*createNested() = val); } - bool remove(int32_t val) - { return removeValue(*createNested() = val); } - bool remove(int64_t val) - { return removeValue(*createNested() = val); } - bool remove(float val) - { return removeValue(*createNested() = val); } - bool remove(double val) - { return removeValue(*createNested() = val); } - DECLARE_IDENTIFIABLE_ABSTRACT(CollectionFieldValue); }; diff --git a/document/src/vespa/document/fieldvalue/doublefieldvalue.h b/document/src/vespa/document/fieldvalue/doublefieldvalue.h index feb15e52223..b9b20bbd24a 100644 --- a/document/src/vespa/document/fieldvalue/doublefieldvalue.h +++ b/document/src/vespa/document/fieldvalue/doublefieldvalue.h @@ -14,7 +14,6 @@ namespace document { class DoubleFieldValue : public NumericFieldValue<double> { public: - typedef std::unique_ptr<DoubleFieldValue> UP; typedef double Number; DoubleFieldValue(Number value = 0) : NumericFieldValue<Number>(value) {} @@ -26,9 +25,8 @@ 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); } }; } // document diff --git a/document/src/vespa/document/fieldvalue/fieldvalue.cpp b/document/src/vespa/document/fieldvalue/fieldvalue.cpp index 8a678ddf968..c69b7169aa0 100644 --- a/document/src/vespa/document/fieldvalue/fieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/fieldvalue.cpp @@ -95,30 +95,6 @@ FieldValue::operator=(vespalib::stringref) throw IllegalArgumentException("Cannot assign string to datatype " + getDataType()->toString(), VESPA_STRLOC); } -FieldValue& -FieldValue::operator=(int32_t) -{ - throw IllegalArgumentException("Cannot assign int to datatype " + getDataType()->toString(), VESPA_STRLOC); -} - -FieldValue& -FieldValue::operator=(int64_t) -{ - throw IllegalArgumentException("Cannot assign long to datatype " + getDataType()->toString(), VESPA_STRLOC); -} - -FieldValue& -FieldValue::operator=(float) -{ - throw IllegalArgumentException("Cannot assign float to datatype " + getDataType()->toString(), VESPA_STRLOC); -} - -FieldValue& -FieldValue::operator=(double) -{ - throw IllegalArgumentException("Cannot assign double to datatype " + getDataType()->toString(), VESPA_STRLOC); -} - char FieldValue::getAsByte() const { diff --git a/document/src/vespa/document/fieldvalue/fieldvalue.h b/document/src/vespa/document/fieldvalue/fieldvalue.h index b0507a6c251..fedb0141391 100644 --- a/document/src/vespa/document/fieldvalue/fieldvalue.h +++ b/document/src/vespa/document/fieldvalue/fieldvalue.h @@ -24,7 +24,6 @@ namespace document { namespace fieldvalue { class IteratorHandler; } -class ByteBuffer; class DataType; class FieldValue : public vespalib::Identifiable @@ -108,13 +107,6 @@ public: /** Override toXml from XmlSerializable to add start/stop tags. */ virtual std::string toXml(const std::string& indent = "") const; - // Utility functions to set commonly used value types. - virtual FieldValue& operator=(vespalib::stringref); - virtual FieldValue& operator=(int32_t); - virtual FieldValue& operator=(int64_t); - virtual FieldValue& operator=(float); - virtual FieldValue& operator=(double); - // Utility functions to unwrap field values if you know the type. /** @@ -187,6 +179,8 @@ public: std::string toString(bool verbose=false, const std::string& indent="") const; virtual void printXml(XmlOutputStream& out) const = 0; + // Utility functions to set commonly used value types. + virtual FieldValue& operator=(vespalib::stringref); private: fieldvalue::ModificationStatus iterateNested(FieldPath::const_iterator start, FieldPath::const_iterator end, fieldvalue::IteratorHandler & handler) const { diff --git a/document/src/vespa/document/fieldvalue/floatfieldvalue.h b/document/src/vespa/document/fieldvalue/floatfieldvalue.h index f33939d8d67..f662c400633 100644 --- a/document/src/vespa/document/fieldvalue/floatfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/floatfieldvalue.h @@ -14,7 +14,6 @@ namespace document { class FloatFieldValue : public NumericFieldValue<float> { public: - typedef std::unique_ptr<FloatFieldValue> UP; typedef float Number; FloatFieldValue(Number value = 0) : NumericFieldValue<Number>(value) {} @@ -26,9 +25,8 @@ 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); } }; } // document diff --git a/document/src/vespa/document/fieldvalue/intfieldvalue.h b/document/src/vespa/document/fieldvalue/intfieldvalue.h index dbe419379a1..d365e34779e 100644 --- a/document/src/vespa/document/fieldvalue/intfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/intfieldvalue.h @@ -14,7 +14,6 @@ namespace document { class IntFieldValue : public NumericFieldValue<int32_t> { public: - typedef std::unique_ptr<IntFieldValue> UP; typedef int32_t Number; IntFieldValue(Number value = 0) : NumericFieldValue<Number>(value) {} @@ -27,7 +26,7 @@ public: using NumericFieldValue<Number>::operator=; DECLARE_IDENTIFIABLE(IntFieldValue); - + static std::unique_ptr<IntFieldValue> make(Number value=0) { return std::make_unique<IntFieldValue>(value); } }; } // document diff --git a/document/src/vespa/document/fieldvalue/literalfieldvalue.cpp b/document/src/vespa/document/fieldvalue/literalfieldvalue.cpp index 9b648400533..7ba537d9cc2 100644 --- a/document/src/vespa/document/fieldvalue/literalfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/literalfieldvalue.cpp @@ -1,10 +1,8 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include "literalfieldvalue.h" #include "literalfieldvalue.hpp" #include <vespa/document/util/stringutil.h> #include <vespa/vespalib/util/xmlstream.h> -#include <sstream> using namespace vespalib::xml; @@ -21,7 +19,7 @@ LiteralFieldValueB::LiteralFieldValueB() : _value = _backing; } -LiteralFieldValueB::~LiteralFieldValueB() { } +LiteralFieldValueB::~LiteralFieldValueB() = default; LiteralFieldValueB::LiteralFieldValueB(const LiteralFieldValueB& other) : FieldValue(other), @@ -32,7 +30,7 @@ LiteralFieldValueB::LiteralFieldValueB(const LiteralFieldValueB& other) _value = _backing; } -LiteralFieldValueB::LiteralFieldValueB(const string& value) +LiteralFieldValueB::LiteralFieldValueB(const stringref & value) : FieldValue(), _value(), _backing(value), @@ -117,44 +115,6 @@ LiteralFieldValueB::syncBacking() const _value = _backing; } - -namespace { -template <typename T> -std::string valueToString(T value) { - std::ostringstream ost; - ost << value; - return ost.str(); -} -} // namespace - -FieldValue& -LiteralFieldValueB::operator=(int32_t value) -{ - setValue(valueToString(value)); - return *this; -} - -FieldValue& -LiteralFieldValueB::operator=(int64_t value) -{ - setValue(valueToString(value)); - return *this; -} - -FieldValue& -LiteralFieldValueB::operator=(float value) -{ - setValue(valueToString(value)); - return *this; -} - -FieldValue& -LiteralFieldValueB::operator=(double value) -{ - setValue(valueToString(value)); - return *this; -} - template class LiteralFieldValue<RawFieldValue, DataType::T_RAW, false>; template class LiteralFieldValue<StringFieldValue, DataType::T_STRING, true>; diff --git a/document/src/vespa/document/fieldvalue/literalfieldvalue.h b/document/src/vespa/document/fieldvalue/literalfieldvalue.h index e84f0c529c7..6e3f0223b20 100644 --- a/document/src/vespa/document/fieldvalue/literalfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/literalfieldvalue.h @@ -32,7 +32,7 @@ public: ~LiteralFieldValueB(); LiteralFieldValueB(const LiteralFieldValueB &); - LiteralFieldValueB(const string& value); + LiteralFieldValueB(const stringref & value); const value_type & getValue() const { sync(); return _backing; } /** @@ -69,10 +69,6 @@ public: bool hasChanged() const override{ return _altered; } FieldValue& operator=(vespalib::stringref) override; - FieldValue& operator=(int32_t) override; - FieldValue& operator=(int64_t) override; - FieldValue& operator=(float) override; - FieldValue& operator=(double) override; protected: void syncBacking() const __attribute__((noinline)); void sync() const { @@ -95,7 +91,7 @@ public: typedef std::unique_ptr<SubClass> UP; LiteralFieldValue() : LiteralFieldValueB() { } - LiteralFieldValue(const string& value) : LiteralFieldValueB(value) { } + LiteralFieldValue(const stringref& value) : LiteralFieldValueB(value) { } const DataType *getDataType() const override; }; diff --git a/document/src/vespa/document/fieldvalue/longfieldvalue.h b/document/src/vespa/document/fieldvalue/longfieldvalue.h index 12a0615e0ad..64ab4332cef 100644 --- a/document/src/vespa/document/fieldvalue/longfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/longfieldvalue.h @@ -14,7 +14,6 @@ namespace document { class LongFieldValue : public NumericFieldValue<int64_t> { public: - typedef std::unique_ptr<LongFieldValue> UP; typedef int64_t Number; LongFieldValue(Number value = 0) : NumericFieldValue<Number>(value) {} @@ -26,8 +25,8 @@ 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/numericfieldvalue.h b/document/src/vespa/document/fieldvalue/numericfieldvalue.h index c094cf0689c..0a557af93d9 100644 --- a/document/src/vespa/document/fieldvalue/numericfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/numericfieldvalue.h @@ -41,10 +41,6 @@ public: int fastCompare(const FieldValue& other) const override final; FieldValue& operator=(vespalib::stringref) override; - FieldValue& operator=(int32_t) override; - FieldValue& operator=(int64_t) override; - FieldValue& operator=(float) override; - FieldValue& operator=(double) override; size_t hash() const override final { return vespalib::hash<Number>()(_value); } char getAsByte() const override; diff --git a/document/src/vespa/document/fieldvalue/numericfieldvalue.hpp b/document/src/vespa/document/fieldvalue/numericfieldvalue.hpp index c4f1fdf13a1..f1bbce5450d 100644 --- a/document/src/vespa/document/fieldvalue/numericfieldvalue.hpp +++ b/document/src/vespa/document/fieldvalue/numericfieldvalue.hpp @@ -123,42 +123,6 @@ NumericFieldValue<Number>::operator=(vespalib::stringref value) } template<typename Number> -FieldValue& -NumericFieldValue<Number>::operator=(int32_t value) -{ - _value = static_cast<Number>(value); - _altered = true; - return *this; -} - -template<typename Number> -FieldValue& -NumericFieldValue<Number>::operator=(int64_t value) -{ - _value = static_cast<Number>(value); - _altered = true; - return *this; -} - -template<typename Number> -FieldValue& -NumericFieldValue<Number>::operator=(float value) -{ - _value = static_cast<Number>(value); - _altered = true; - return *this; -} - -template<typename Number> -FieldValue& -NumericFieldValue<Number>::operator=(double value) -{ - _value = static_cast<Number>(value); - _altered = true; - return *this; -} - -template<typename Number> char NumericFieldValue<Number>::getAsByte() const { diff --git a/document/src/vespa/document/fieldvalue/shortfieldvalue.h b/document/src/vespa/document/fieldvalue/shortfieldvalue.h index f2047d1a521..fa61c37c4eb 100644 --- a/document/src/vespa/document/fieldvalue/shortfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/shortfieldvalue.h @@ -27,9 +27,8 @@ 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); } }; } // document diff --git a/document/src/vespa/document/fieldvalue/stringfieldvalue.h b/document/src/vespa/document/fieldvalue/stringfieldvalue.h index 15aeeccd0de..17a0302f6f9 100644 --- a/document/src/vespa/document/fieldvalue/stringfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/stringfieldvalue.h @@ -24,7 +24,7 @@ public: typedef std::vector<SpanTree::UP> SpanTrees; StringFieldValue() : Parent(), _annotationData() { } - StringFieldValue(const string &value) + StringFieldValue(const vespalib::stringref &value) : Parent(value), _annotationData() { } StringFieldValue(const StringFieldValue &rhs); @@ -57,6 +57,8 @@ 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: void doClearSpanTrees(); diff --git a/document/src/vespa/document/fieldvalue/structfieldvalue.cpp b/document/src/vespa/document/fieldvalue/structfieldvalue.cpp index 555964d8b34..fbe6dadb320 100644 --- a/document/src/vespa/document/fieldvalue/structfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/structfieldvalue.cpp @@ -79,14 +79,16 @@ bool StructFieldValue::serializeField(int field_id, uint16_t version, FieldValue } } -void StructFieldValue::getRawFieldIds(vector<int> &raw_ids) const { - raw_ids.clear(); +vector<int> +StructFieldValue::getRawFieldIds() const { + vector<int> raw_ids; raw_ids.reserve(_fields.getEntries().size()); for (const SerializableArray::Entry & entry : _fields.getEntries()) { raw_ids.emplace_back(entry.id()); } sort(raw_ids.begin(), raw_ids.end()); raw_ids.erase(unique(raw_ids.begin(), raw_ids.end()), raw_ids.end()); + return raw_ids; } void @@ -242,10 +244,8 @@ StructFieldValue::compare(const FieldValue& otherOrg) const } const auto & other = static_cast<const StructFieldValue&>(otherOrg); - std::vector<int> a; - getRawFieldIds(a); - std::vector<int> b; - other.getRawFieldIds(b); + std::vector<int> a = getRawFieldIds(); + std::vector<int> b = other.getRawFieldIds(); for (size_t i(0); i < std::min(a.size(), b.size()); i++) { if (a[i] != b[i]) { @@ -337,12 +337,9 @@ struct StructFieldValue::FieldIterator : public StructuredIterator { explicit FieldIterator(const StructFieldValue& s) : _struct(s), - _ids(), + _ids(s.getRawFieldIds()), _cur(_ids.begin()) - { - s.getRawFieldIds(_ids); - _cur = _ids.begin(); - } + { } void skipTo(int fieldId) { while (_cur != _ids.end() && fieldId != *_cur) { diff --git a/document/src/vespa/document/fieldvalue/structfieldvalue.h b/document/src/vespa/document/fieldvalue/structfieldvalue.h index ab35dc04421..24e143ddc27 100644 --- a/document/src/vespa/document/fieldvalue/structfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/structfieldvalue.h @@ -54,7 +54,7 @@ public: uint16_t getVersion() const { return _version; } // raw_ids may contain ids for elements not in the struct's datatype. - void getRawFieldIds(std::vector<int> &raw_ids) const; + std::vector<int> getRawFieldIds() const; void getRawFieldIds(std::vector<int> &raw_ids, const FieldSet& fieldSet) const; void accept(FieldValueVisitor &visitor) override { visitor.visit(*this); } @@ -98,7 +98,6 @@ private: VESPA_DLL_LOCAL const StructDataType & getStructType() const; struct FieldIterator; - friend struct FieldIterator; StructuredIterator::UP getIterator(const Field* toFind) const override; diff --git a/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp b/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp index becdfdabb5f..53f75cb2e73 100644 --- a/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp @@ -172,20 +172,6 @@ StructuredFieldValue::onIterateNested(PathRange nested, IteratorHandler & handle } } -using ConstCharP = const char *; -template void StructuredFieldValue::set(const Field& field, int32_t value); -template void StructuredFieldValue::set(const Field& field, int64_t value); -template void StructuredFieldValue::set(const Field& field, double value); -template void StructuredFieldValue::set(const Field& field, ConstCharP value); -template void StructuredFieldValue::set(const Field& field, vespalib::stringref value); -template void StructuredFieldValue::set(const Field& field, vespalib::string value); -template void StructuredFieldValue::set(vespalib::stringref field, int32_t value); -template void StructuredFieldValue::set(vespalib::stringref field, int64_t value); -template void StructuredFieldValue::set(vespalib::stringref field, double value); -template void StructuredFieldValue::set(vespalib::stringref field, ConstCharP value); -template void StructuredFieldValue::set(vespalib::stringref field, vespalib::stringref value); -template void StructuredFieldValue::set(vespalib::stringref field, vespalib::string value); - template std::unique_ptr<MapFieldValue> StructuredFieldValue::getAs<MapFieldValue>(const Field &field) const; template std::unique_ptr<ArrayFieldValue> StructuredFieldValue::getAs<ArrayFieldValue>(const Field &field) const; template std::unique_ptr<WeightedSetFieldValue> StructuredFieldValue::getAs<WeightedSetFieldValue>(const Field &field) const; diff --git a/document/src/vespa/document/fieldvalue/structuredfieldvalue.h b/document/src/vespa/document/fieldvalue/structuredfieldvalue.h index b1b88323a3b..9d79b6279a4 100644 --- a/document/src/vespa/document/fieldvalue/structuredfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/structuredfieldvalue.h @@ -152,6 +152,12 @@ public: void setValue(const Field& field, FieldValue::UP value) { setFieldValue(field, std::move(value)); } + void setValue(vespalib::stringref fieldName, const FieldValue& value) { + setFieldValue(getField(fieldName), value); + } + void setValue(vespalib::stringref fieldName, FieldValue::UP value) { + setFieldValue(getField(fieldName), std::move(value)); + } /** Remove the value of given field if it is set. */ //These are affected by the begin/commitTanasaction @@ -166,13 +172,6 @@ public: void remove(vespalib::stringref fieldName) { removeFieldValue(getField(fieldName)); } - void setValue(vespalib::stringref fieldName, const FieldValue& value) { - setFieldValue(getField(fieldName), value); - } - template<typename PrimitiveType> - void set(const Field& field, PrimitiveType value); - template<typename PrimitiveType> - void set(vespalib::stringref fieldName, PrimitiveType value); size_t getSetFieldCount() const { size_t count = 0; diff --git a/document/src/vespa/document/fieldvalue/structuredfieldvalue.hpp b/document/src/vespa/document/fieldvalue/structuredfieldvalue.hpp index df02506c076..4b347d7cc07 100644 --- a/document/src/vespa/document/fieldvalue/structuredfieldvalue.hpp +++ b/document/src/vespa/document/fieldvalue/structuredfieldvalue.hpp @@ -20,20 +20,4 @@ StructuredFieldValue::getAs(const Field &field) const { return std::unique_ptr<T>(t); } -template<typename PrimitiveType> -void -StructuredFieldValue::set(const Field& field, PrimitiveType value) -{ - FieldValue::UP fval(field.getDataType().createFieldValue()); - *fval = value; - setFieldValue(field, std::move(fval)); -} - -template<typename PrimitiveType> -void -StructuredFieldValue::set(vespalib::stringref fieldName, PrimitiveType value) -{ - set(getField(fieldName), value); -} - } // document diff --git a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp index 6b80ceb1f6e..2a3726095df 100644 --- a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp @@ -59,7 +59,7 @@ WeightedSetFieldValue::add(const FieldValue& key, int weight) _map.erase(key); return false; } - return _map.insert(FieldValue::UP(key.clone()), std::make_unique<IntFieldValue>(weight)); + return _map.insert(FieldValue::UP(key.clone()), IntFieldValue::make(weight)); } bool @@ -67,14 +67,14 @@ WeightedSetFieldValue::addIgnoreZeroWeight(const FieldValue& key, int32_t weight { verifyKey(key); _altered = true; - return _map.insert(FieldValue::UP(key.clone()), std::make_unique<IntFieldValue>(weight)); + 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), std::make_unique<IntFieldValue>(weight)); + _map.push_back(std::move(key), IntFieldValue::make(weight)); } void diff --git a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h index b88c44085ba..d58819607b4 100644 --- a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h @@ -64,8 +64,7 @@ public: bool addIgnoreZeroWeight(const FieldValue&, int32_t weight = 1); void push_back(FieldValue::UP, int32_t weight); void increment(const FieldValue& fval, int val = 1); - void decrement(const FieldValue& fval, int val = 1) - { increment(fval, -1*val); } + void decrement(const FieldValue& fval, int val = 1) { increment(fval, -1*val); } int32_t get(const FieldValue&, int32_t defaultValue = 0) const; bool isEmpty() const override { return _map.isEmpty(); } @@ -76,13 +75,12 @@ public: FieldValue& assign(const FieldValue&) override; WeightedSetFieldValue* clone() const override { return new WeightedSetFieldValue(*this); } - virtual int compare(const FieldValue&) const override; - virtual void printXml(XmlOutputStream& out) const override; - virtual void print(std::ostream& out, bool verbose, - const std::string& indent) const override; - virtual bool hasChanged() const override; + 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. + // Implements iterating through internal content. typedef WeightedFieldValueMap::const_iterator const_iterator; typedef WeightedFieldValueMap::iterator iterator; @@ -95,54 +93,7 @@ public: const_iterator find(const FieldValue& fv) const; iterator find(const FieldValue& fv); - // Utility functions for easy use of weighted sets of primitives - - bool add(vespalib::stringref val, int32_t weight = 1) - { return add(*createNested() = val, weight); } - bool add(int32_t val, int32_t weight = 1) - { return add(*createNested() = val, weight); } - bool add(int64_t val, int32_t weight = 1) - { return add(*createNested() = val, weight); } - bool add(float val, int32_t weight = 1) - { return add(*createNested() = val, weight); } - bool add(double val, int32_t weight = 1) - { return add(*createNested() = val, weight); } - - int32_t get(vespalib::stringref val) const - { return get(*createNested() = val); } - int32_t get(int32_t val) const - { return get(*createNested() = val); } - int32_t get(int64_t val) const - { return get(*createNested() = val); } - int32_t get(float val) const - { return get(*createNested() = val); } - int32_t get(double val) const - { return get(*createNested() = val); } - - void increment(vespalib::stringref val, int32_t weight = 1) - { increment(*createNested() = val, weight); } - void increment(int32_t val, int32_t weight = 1) - { increment(*createNested() = val, weight); } - void increment(int64_t val, int32_t weight = 1) - { increment(*createNested() = val, weight); } - void increment(float val, int32_t weight = 1) - { increment(*createNested() = val, weight); } - void increment(double val, int32_t weight = 1) - { increment(*createNested() = val, weight); } - - void decrement(vespalib::stringref val, int32_t weight = 1) - { decrement(*createNested() = val, weight); } - void decrement(int32_t val, int32_t weight = 1) - { decrement(*createNested() = val, weight); } - void decrement(int64_t val, int32_t weight = 1) - { decrement(*createNested() = val, weight); } - void decrement(float val, int32_t weight = 1) - { decrement(*createNested() = val, weight); } - void decrement(double val, int32_t weight = 1) - { decrement(*createNested() = val, weight); } - DECLARE_IDENTIFIABLE_ABSTRACT(WeightedSetFieldValue); - }; } // document diff --git a/document/src/vespa/document/test/fieldvalue_helpers.h b/document/src/vespa/document/test/fieldvalue_helpers.h new file mode 100644 index 00000000000..a7d899b385f --- /dev/null +++ b/document/src/vespa/document/test/fieldvalue_helpers.h @@ -0,0 +1,71 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <vespa/document/fieldvalue/collectionfieldvalue.h> +#include <vespa/document/fieldvalue/weightedsetfieldvalue.h> +#include <vespa/document/fieldvalue/longfieldvalue.h> +#include <vespa/document/fieldvalue/floatfieldvalue.h> +#include <vespa/document/fieldvalue/doublefieldvalue.h> + +namespace document { + +class CollectionHelper { +public: + CollectionHelper(CollectionFieldValue &value) : _cfv(value) {} + + // Convenience functions for using primitives directly + bool add(vespalib::stringref val) { return _cfv.add(*_cfv.createNested() = val); } + bool add(int32_t val) { return _cfv.add(_cfv.createNested()->assign(IntFieldValue(val))); } + bool add(int64_t val) { return _cfv.add(_cfv.createNested()->assign(LongFieldValue(val))); } + bool add(float val) { return _cfv.add(_cfv.createNested()->assign(FloatFieldValue(val))); } + bool add(double val) { return _cfv.add(_cfv.createNested()->assign(DoubleFieldValue(val))); } + + bool contains(vespalib::stringref val) { return _cfv.contains(*_cfv.createNested() = val); } + bool contains(int32_t val) { return _cfv.contains(_cfv.createNested()->assign(IntFieldValue(val))); } + bool contains(int64_t val) { return _cfv.contains(_cfv.createNested()->assign(LongFieldValue(val))); } + bool contains(float val) { return _cfv.contains(_cfv.createNested()->assign(FloatFieldValue(val))); } + bool contains(double val) { return _cfv.contains(_cfv.createNested()->assign(DoubleFieldValue(val))); } + + bool remove(vespalib::stringref val) { return _cfv.remove(*_cfv.createNested() = val); } + bool remove(int32_t val) { return _cfv.remove(_cfv.createNested()->assign(IntFieldValue(val))); } + bool remove(int64_t val) { return _cfv.remove(_cfv.createNested()->assign(LongFieldValue(val))); } + bool remove(float val) { return _cfv.remove(_cfv.createNested()->assign(FloatFieldValue(val))); } + bool remove(double val) { return _cfv.remove(_cfv.createNested()->assign(DoubleFieldValue(val))); } +private: + CollectionFieldValue & _cfv; +}; + +class WSetHelper { +public: + WSetHelper(WeightedSetFieldValue & ws) : _ws(ws) { } + + // Utility functions for easy use of weighted sets of primitives + + bool add(vespalib::stringref val, int32_t weight = 1) { return _ws.add(*_ws.createNested() = val, weight); } + bool add(int32_t val, int32_t weight = 1) { return _ws.add(_ws.createNested()->assign(IntFieldValue(val)), weight); } + bool add(int64_t val, int32_t weight = 1) { return _ws.add(_ws.createNested()->assign(LongFieldValue(val)), weight); } + bool add(float val, int32_t weight = 1) { return _ws.add(_ws.createNested()->assign(FloatFieldValue(val)), weight); } + bool add(double val, int32_t weight = 1) { return _ws.add(_ws.createNested()->assign(DoubleFieldValue(val)), weight); } + + int32_t get(vespalib::stringref val) const { return _ws.get(*_ws.createNested() = val); } + int32_t get(int32_t val) const { return _ws.get(_ws.createNested()->assign(IntFieldValue(val))); } + int32_t get(int64_t val) const { return _ws.get(_ws.createNested()->assign(LongFieldValue(val))); } + int32_t get(float val) const { return _ws.get(_ws.createNested()->assign(FloatFieldValue(val))); } + int32_t get(double val) const { return _ws.get(_ws.createNested()->assign(DoubleFieldValue(val))); } + + void increment(vespalib::stringref val, int32_t weight = 1) { _ws.increment(*_ws.createNested() = val, weight); } + void increment(int32_t val, int32_t weight = 1) { _ws.increment(_ws.createNested()->assign(IntFieldValue(val)), weight); } + void increment(int64_t val, int32_t weight = 1) { _ws.increment(_ws.createNested()->assign(LongFieldValue(val)), weight); } + void increment(float val, int32_t weight = 1) { _ws.increment(_ws.createNested()->assign(FloatFieldValue(val)), weight); } + void increment(double val, int32_t weight = 1) { _ws.increment(_ws.createNested()->assign(DoubleFieldValue(val)), weight); } + + void decrement(vespalib::stringref val, int32_t weight = 1) { _ws.decrement(*_ws.createNested() = val, weight); } + void decrement(int32_t val, int32_t weight = 1) { _ws.decrement(_ws.createNested()->assign(IntFieldValue(val)), weight); } + void decrement(int64_t val, int32_t weight = 1) { _ws.decrement(_ws.createNested()->assign(LongFieldValue(val)), weight); } + void decrement(float val, int32_t weight = 1) { _ws.decrement(_ws.createNested()->assign(FloatFieldValue(val)), weight); } + void decrement(double val, int32_t weight = 1) { _ws.decrement(_ws.createNested()->assign(DoubleFieldValue(val)), weight); } +private: + WeightedSetFieldValue & _ws; +}; +} |