/* * EventMatchTree.cpp * * Created on: 27.08.2015 * Author: baetz */ #include #include #include #include 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) { 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) { //TODO: What if first deletion fails? factory.destroy(position.element->value); return factory.destroy(position.element); }