#include "EventIdRangeMatcher.h" #include "EventMatchTree.h" #include "ReporterRangeMatcher.h" #include "SeverityRangeMatcher.h" EventMatchTree::EventMatchTree(StorageManagerIF* storageBackend, bool invertedMatch) : MatchTree(end(), 1), factory(storageBackend), invertedMatch( invertedMatch) { } EventMatchTree::~EventMatchTree() { } bool EventMatchTree::match(EventMessage* number) { if (invertedMatch) { return !MatchTree::match(number); } else { return MatchTree::match(number); } } ReturnValue_t EventMatchTree::addMatch(EventId_t idFrom, EventId_t idTo, bool idInverted, object_id_t reporterFrom, object_id_t reporterTo, bool reporterInverted) { if (idFrom == 0) { //Assuming all events shall be forwarded. idTo = 0; idInverted = true; } if (idTo == 0) { idTo = idFrom; } iterator lastTest; ReturnValue_t result = findOrInsertRangeMatcher(begin(), idFrom, idTo, idInverted, &lastTest); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } if (reporterFrom == 0) { //No need to add another AND branch return RETURN_OK; } if (reporterTo == 0) { reporterTo = reporterFrom; } return findOrInsertRangeMatcher( lastTest.left(), reporterFrom, reporterTo, reporterInverted, &lastTest); } ReturnValue_t EventMatchTree::removeMatch(EventId_t idFrom, EventId_t idTo, bool idInverted, object_id_t reporterFrom, object_id_t reporterTo, bool reporterInverted) { iterator foundElement; if (idFrom == 0) { //Assuming a "forward all events" request. idTo = 0; idInverted = true; } if (idTo == 0) { idTo = idFrom; } foundElement = findRangeMatcher(begin(), idFrom, idTo, idInverted); if (foundElement == end()) { return NO_MATCH; //Can't tell if too detailed or just not found. } if (reporterFrom == 0) { if (foundElement.left() == end()) { return removeElementAndReconnectChildren(foundElement); } else { return TOO_GENERAL_REQUEST; } } if (reporterTo == 0) { reporterTo = reporterFrom; } foundElement = findRangeMatcher( foundElement.left(), reporterFrom, reporterTo, reporterInverted); if (foundElement == end()) { return NO_MATCH; } else { return removeElementAndReconnectChildren(foundElement); } } template inline ReturnValue_t EventMatchTree::findOrInsertRangeMatcher(iterator start, VALUE_T idFrom, VALUE_T idTo, bool inverted, iterator* lastTest) { bool attachToBranch = AND; iterator iter = start; while (iter != end()) { INSERTION_T* matcher = static_cast(*iter); attachToBranch = OR; *lastTest = iter; if ((matcher->rangeMatcher.lowerBound == idFrom) && (matcher->rangeMatcher.upperBound == idTo) && (matcher->rangeMatcher.inverted == inverted)) { return RETURN_OK; } else { iter = iter.right(); } } //Only reached if nothing was found. SerializeableMatcherIF* newContent = factory.generate< INSERTION_T>(idFrom, idTo, inverted); if (newContent == NULL) { return FULL; } Node* newNode = factory.generate(newContent); if (newNode == NULL) { //Need to make sure partially generated content is deleted, otherwise, that's a leak. factory.destroy(static_cast(newContent)); return FULL; } *lastTest = insert(attachToBranch, *lastTest, newNode); if (*lastTest == end()) { //This actaully never fails, so creating a dedicated returncode seems an overshoot. return RETURN_FAILED; } return RETURN_OK; } template EventMatchTree::iterator EventMatchTree::findRangeMatcher(iterator start, VALUE_T idFrom, VALUE_T idTo, bool inverted) { iterator iter = start; while (iter != end()) { INSERTION_T* matcher = static_cast(*iter); if ((matcher->rangeMatcher.lowerBound == idFrom) && (matcher->rangeMatcher.upperBound == idTo) && (matcher->rangeMatcher.inverted == inverted)) { break; } else { iter = iter.right(); //next OR element } } return iter; } ReturnValue_t EventMatchTree::cleanUpElement(iterator position) { factory.destroy(position.element->value); //If deletion fails, delete element anyway, nothing we can do. //SHOULDO: Throw event, or write debug output. return factory.destroy(position.element); }