summaryrefslogtreecommitdiff
path: root/src/core/model/Document.cpp
diff options
context:
space:
mode:
authorBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-02-15 20:16:53 +0100
committerBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-02-15 20:16:53 +0100
commit76c33b56df9ae13ba7e8c1f3d7ec6bc2118f3e26 (patch)
treed0f32df9923e5dcf2dbcc5be8cf4c6d6033598d1 /src/core/model/Document.cpp
parent67f25b93b847b43a62a4148e626481c3f6d0cd9b (diff)
fixed a bug in instance counting in DocumentEntity::doValidate and made the validation process faster and more compact using advanced programming techniques.
Diffstat (limited to 'src/core/model/Document.cpp')
-rw-r--r--src/core/model/Document.cpp62
1 files changed, 29 insertions, 33 deletions
diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp
index a2ba5cf..4e101fc 100644
--- a/src/core/model/Document.cpp
+++ b/src/core/model/Document.cpp
@@ -135,6 +135,15 @@ bool DocumentEntity::doValidate(Logger &logger) const
continue;
}
+ std::unordered_set<StructuredClass *> childClasses;
+ {
+ NodeVector<StructuredClass> tmp =
+ fieldDescs[f]->getChildrenWithSubclasses();
+ for (auto s : tmp) {
+ childClasses.insert(s.get());
+ }
+ }
+
// we can do a faster check if this field is empty.
if (fields[f].size() == 0) {
// if this field is optional, an empty field is valid anyways.
@@ -145,7 +154,7 @@ bool DocumentEntity::doValidate(Logger &logger) const
* if it is not optional we have to check if zero is a valid
* cardinality.
*/
- for (auto childClass : fieldDescs[f]->getChildren()) {
+ for (auto childClass : childClasses) {
const size_t min =
childClass->getCardinality().asCardinality().min();
if (min > 0) {
@@ -163,15 +172,10 @@ bool DocumentEntity::doValidate(Logger &logger) const
continue;
}
- // create a set of allowed classes identified by their unique id.
- std::set<ManagedUid> childClasses;
- for (auto &childClass : fieldDescs[f]->getChildren()) {
- childClasses.insert(childClass->getUid());
- }
// store the actual numbers of children for each child class in a map
- std::map<ManagedUid, unsigned int> nums;
+ std::unordered_map<StructuredClass *, unsigned int> nums;
- // iterate over every actual child of this DocumentEntity
+ // iterate over every actual child of this field
for (auto child : fields[f]) {
// check if the parent reference is correct.
if (child->getParent() != subInst) {
@@ -195,25 +199,11 @@ bool DocumentEntity::doValidate(Logger &logger) const
}
// otherwise this is a StructuredEntity
Handle<StructuredEntity> c = child.cast<StructuredEntity>();
+ StructuredClass *classPtr =
+ c->getDescriptor().cast<StructuredClass>().get();
- ManagedUid id = c->getDescriptor()->getUid();
// check if its class is allowed.
- bool allowed = childClasses.find(id) != childClasses.end();
- /*
- * if it is not allowed directly, we have to check if the class is a
- * child of a permitted class.
- */
- if (!allowed) {
- for (auto childClass : fieldDescs[f]->getChildren()) {
- if (c->getDescriptor()
- .cast<StructuredClass>()
- ->isSubclassOf(childClass)) {
- allowed = true;
- id = childClass->getUid();
- }
- }
- }
- if (!allowed) {
+ if (childClasses.find(classPtr) == childClasses.end()) {
logger.error(
std::string("An instance of \"") +
c->getDescriptor()->getName() +
@@ -224,18 +214,24 @@ bool DocumentEntity::doValidate(Logger &logger) const
valid = false;
continue;
}
- // note the number of occurences.
- const auto &n = nums.find(id);
- if (n != nums.end()) {
- n->second++;
- } else {
- nums.emplace(id, 1);
+ // note the number of occurences for this class and all
+ // superclasses, because a subclass instance should count for
+ // superclasses as well.
+ while (classPtr != nullptr &&
+ childClasses.find(classPtr) != childClasses.end()) {
+ const auto &n = nums.find(classPtr);
+ if (n != nums.end()) {
+ n->second++;
+ } else {
+ nums.emplace(classPtr, 1);
+ }
+ classPtr = classPtr->getSuperclass().get();
}
}
// now check if the cardinalities are right.
- for (auto childClass : fieldDescs[f]->getChildren()) {
- const auto &n = nums.find(childClass->getUid());
+ for (auto childClass : childClasses) {
+ const auto &n = nums.find(childClass);
unsigned int num = 0;
if (n != nums.end()) {
num = n->second;