X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/669d793c17f7ff44ba4b111d36d1f63512f64195..45c3a73f3553c8d365f61eaa8445f038db9bdb8f:/src/mc/explo/udpor/Unfolding.cpp diff --git a/src/mc/explo/udpor/Unfolding.cpp b/src/mc/explo/udpor/Unfolding.cpp index 6a81ff205e..587d4e93c8 100644 --- a/src/mc/explo/udpor/Unfolding.cpp +++ b/src/mc/explo/udpor/Unfolding.cpp @@ -9,23 +9,23 @@ namespace simgrid::mc::udpor { -void Unfolding::remove(const EventSet& events) +void Unfolding::mark_finished(const EventSet& events) { - for (const auto e : events) { - remove(e); + for (const auto* e : events) { + mark_finished(e); } } -void Unfolding::remove(const UnfoldingEvent* e) +void Unfolding::mark_finished(const UnfoldingEvent* e) { if (e == nullptr) { throw std::invalid_argument("Expected a non-null pointer to an event, but received NULL"); } - this->global_events_.erase(e); - this->event_handles.remove(e); + this->U.remove(e); + this->G.insert(e); } -void Unfolding::insert(std::unique_ptr e) +const UnfoldingEvent* Unfolding::insert(std::unique_ptr e) { const UnfoldingEvent* handle = e.get(); if (auto loc = this->global_events_.find(handle); loc != this->global_events_.end()) { @@ -36,33 +36,41 @@ void Unfolding::insert(std::unique_ptr e) "This will result in a double free error and must be fixed."); } - // Map the handle to its owner - this->event_handles.insert(handle); - this->global_events_[handle] = std::move(e); -} + // Attempt to search first for an event in `U`. If it exists, we use that event + // instead of `e` since it is semantically equivalent to `e` (i.e. `e` is + // effectively already contained in the unfolding) + if (auto loc = std::find_if(U.begin(), U.end(), [=](const auto e_i) { return *e_i == *handle; }); loc != U.end()) { + // Return the handle to that event and ignore adding in a duplicate event + return *loc; + } -bool Unfolding::contains_event_equivalent_to(const UnfoldingEvent* e) const -{ - // Notice the use of `==` equality here. `e` may not be contained in the - // unfolding; but some event which is "equivalent" to it could be. - for (const auto event : *this) { - if (*event == *e) { - return true; - } + // Then look for `e` in `G`. It's possible `e` was already constructed + // in the past, in which case we can simply re-use it. + // + // Note, though, that in this case we must move the event in `G` into + // `U`: we've inserted `e` into the unfolding, so we expect it to be in `U` + if (auto loc = std::find_if(G.begin(), G.end(), [=](const auto e_i) { return *e_i == *handle; }); loc != G.end()) { + const auto* e_equiv = *loc; + G.remove(e_equiv); + U.insert(e_equiv); + return e_equiv; } - return false; + + // Otherwise `e` is truly a "new" event + this->U.insert(handle); + this->event_handles.insert(handle); + this->global_events_[handle] = std::move(e); + return handle; } EventSet Unfolding::get_immediate_conflicts_of(const UnfoldingEvent* e) const { EventSet immediate_conflicts; - - for (const auto event : *this) { + for (const auto* event : U) { if (event->immediately_conflicts_with(e)) { - immediate_conflicts.insert(e); + immediate_conflicts.insert(event); } } - return immediate_conflicts; }