aboutsummaryrefslogtreecommitdiffstats
path: root/document
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2020-08-14 13:12:51 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2020-08-14 13:12:51 +0000
commitdf5a57673b782ab36ef8d24893d607f04514600e (patch)
tree7f9ce1717105693e7cd1530246efe831a1ef1a46 /document
parent7bf5c4d363334993135f9edf77d9bbed306d03e4 (diff)
Make sure the entries in the set are unique.
Make both a less and equal operator so std::unique can be used to. Add and interface so that whole sets can be tested effectively if they are subsets.
Diffstat (limited to 'document')
-rw-r--r--document/src/tests/fieldsettest.cpp7
-rw-r--r--document/src/vespa/document/base/field.cpp16
-rw-r--r--document/src/vespa/document/base/field.h12
-rw-r--r--document/src/vespa/document/datatype/structdatatype.cpp2
-rw-r--r--document/src/vespa/document/fieldset/fieldsetrepo.cpp4
-rw-r--r--document/src/vespa/document/fieldset/fieldsets.cpp2
6 files changed, 31 insertions, 12 deletions
diff --git a/document/src/tests/fieldsettest.cpp b/document/src/tests/fieldsettest.cpp
index 8a01c53c278..29581ff4549 100644
--- a/document/src/tests/fieldsettest.cpp
+++ b/document/src/tests/fieldsettest.cpp
@@ -275,9 +275,10 @@ TEST(FieldCollectionTest, testHash ) {
const DocumentTypeRepo& repo = testDocMan.getTypeRepo();
const DocumentType & type = *repo.getDocumentType("testdoctype1");
EXPECT_EQ(0ul, FieldCollection(type, Field::Set::Builder().build()).hash());
- EXPECT_EQ(0x548599858c77ef83ul, FieldCollection(type, Field::Set::Builder().insert(&type.getField("headerval")).build()).hash());
- EXPECT_EQ(0x4a7ff2406d36a9b0ul, FieldCollection(type, Field::Set::Builder().insert(&type.getField("headerval")).insert(&type.getField("hstringval")).build()).hash());
- EXPECT_EQ(0x1e0918531b19734ul, FieldCollection(type, Field::Set::Builder().insert(&type.getField("hstringval")).build()).hash());
+ EXPECT_EQ(0x548599858c77ef83ul, FieldCollection(type, Field::Set::Builder().add(&type.getField("headerval")).build()).hash());
+ EXPECT_EQ(0x4a7ff2406d36a9b0ul, FieldCollection(type, Field::Set::Builder().add(&type.getField("headerval")).add(
+ &type.getField("hstringval")).build()).hash());
+ EXPECT_EQ(0x1e0918531b19734ul, FieldCollection(type, Field::Set::Builder().add(&type.getField("hstringval")).build()).hash());
}
} // document
diff --git a/document/src/vespa/document/base/field.cpp b/document/src/vespa/document/base/field.cpp
index 7f1a598cd76..fb814fc5f17 100644
--- a/document/src/vespa/document/base/field.cpp
+++ b/document/src/vespa/document/base/field.cpp
@@ -14,15 +14,25 @@ namespace document {
Field::Set::Set(std::vector<CPtr> fields)
: _fields(std::move(fields))
{
- std::sort(_fields.begin(), _fields.end(), Field::FieldPtrComparator());
+ std::sort(_fields.begin(), _fields.end(), Field::FieldPtrLess());
+ _fields.erase(std::unique(_fields.begin(), _fields.end(), Field::FieldPtrEqual()), _fields.end());
}
bool
Field::Set::contains(const Field & field) const {
- return std::binary_search(_fields.begin(), _fields.end(), &field, Field::FieldPtrComparator());
+ return std::binary_search(_fields.begin(), _fields.end(), &field, Field::FieldPtrLess());
}
-Field::Field() : Field("", 0, *DataType::INT) { }
+bool
+Field::Set::contains(const Set & fields) const {
+ return std::includes(_fields.begin(), _fields.end(),
+ fields._fields.begin(), fields._fields.end(),
+ Field::FieldPtrLess());
+}
+
+Field::Field()
+ : Field("", 0, *DataType::INT)
+{ }
Field::Field(vespalib::stringref name, int fieldId, const DataType& dataType)
: FieldBase(name),
diff --git a/document/src/vespa/document/base/field.h b/document/src/vespa/document/base/field.h
index cf876903dfa..7580b2b692f 100644
--- a/document/src/vespa/document/base/field.h
+++ b/document/src/vespa/document/base/field.h
@@ -32,27 +32,35 @@ public:
using SP = std::shared_ptr<Field>;
using CPtr = const Field *;
- struct FieldPtrComparator {
+ struct FieldPtrLess {
bool operator()(CPtr f1, CPtr f2) const {
return (*f1 < *f2);
}
};
+ struct FieldPtrEqual {
+ bool operator()(CPtr f1, CPtr f2) const {
+ return (*f1 == *f2);
+ }
+ };
+
class Set {
public:
class Builder {
public:
Builder & reserve(size_t sz) { _vector.reserve(sz); return *this; }
- Builder & insert(CPtr field) { _vector.emplace_back(field); return *this; }
+ Builder & add(CPtr field) { _vector.push_back(field); return *this; }
Set build() { return Set(std::move(_vector)); }
private:
std::vector<CPtr> _vector;
};
bool contains(const Field & field) const;
+ bool contains(const Set & field) const;
size_t size() const { return _fields.size(); }
bool empty() const { return _fields.empty(); }
const CPtr * begin() const { return &_fields[0]; }
const CPtr * end() const { return begin() + _fields.size(); }
+ static Set emptySet() { return Builder().build(); }
private:
explicit Set(std::vector<CPtr> fields);
std::vector<CPtr> _fields;
diff --git a/document/src/vespa/document/datatype/structdatatype.cpp b/document/src/vespa/document/datatype/structdatatype.cpp
index 11af020c465..c0c63ddb37f 100644
--- a/document/src/vespa/document/datatype/structdatatype.cpp
+++ b/document/src/vespa/document/datatype/structdatatype.cpp
@@ -167,7 +167,7 @@ StructDataType::getFieldSet() const
Field::Set::Builder builder;
builder.reserve(_idFieldMap.size());
for (const auto & entry : _idFieldMap) {
- builder.insert(entry.second.get());
+ builder.add(entry.second.get());
}
return builder.build();
}
diff --git a/document/src/vespa/document/fieldset/fieldsetrepo.cpp b/document/src/vespa/document/fieldset/fieldsetrepo.cpp
index 5cc3e548d82..33cbf6185c4 100644
--- a/document/src/vespa/document/fieldset/fieldsetrepo.cpp
+++ b/document/src/vespa/document/fieldset/fieldsetrepo.cpp
@@ -49,10 +49,10 @@ parseFieldCollection(const DocumentTypeRepo& repo,
const DocumentType::FieldSet * fs = type.getFieldSet(token);
if (fs) {
for (const auto & fieldName : fs->getFields()) {
- builder.insert(&type.getField(fieldName));
+ builder.add(&type.getField(fieldName));
}
} else {
- builder.insert(&type.getField(token));
+ builder.add(&type.getField(token));
}
}
return std::make_unique<FieldCollection>(type, builder.build());
diff --git a/document/src/vespa/document/fieldset/fieldsets.cpp b/document/src/vespa/document/fieldset/fieldsets.cpp
index 115ad37343d..317c1743bb5 100644
--- a/document/src/vespa/document/fieldset/fieldsets.cpp
+++ b/document/src/vespa/document/fieldset/fieldsets.cpp
@@ -42,7 +42,7 @@ FieldCollection::contains(const FieldSet& fields) const
return _set.contains(static_cast<const Field &>(fields));
case Type::SET: {
const auto & coll = static_cast<const FieldCollection&>(fields);
- return std::includes(_set.begin(), _set.end(), coll.getFields().begin(), coll.getFields().end(), Field::FieldPtrComparator());
+ return _set.contains(coll.getFields());
}
case Type::NONE:
case Type::DOCID: