diff options
author | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-02-15 20:16:53 +0100 |
---|---|---|
committer | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-02-15 20:16:53 +0100 |
commit | 76c33b56df9ae13ba7e8c1f3d7ec6bc2118f3e26 (patch) | |
tree | d0f32df9923e5dcf2dbcc5be8cf4c6d6033598d1 /src/core/model/Document.cpp | |
parent | 67f25b93b847b43a62a4148e626481c3f6d0cd9b (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.cpp | 62 |
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; |