Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
|
#include <update_trackers.h>
Public Types | |
using | IdDataPair = std::pair<UpdateTrackerId, std::unique_ptr<Data>> |
A pair (tracker_id, tracker_data). | |
Public Member Functions | |
template<typename... T> | |
UpdateTrackerId | NewUpdateTracker (T &&... args) |
void | DeleteUpdateTracker (UpdateTrackerId update_tracker) |
const std::vector< IdDataPair > & | GetUpdatedTrackers () |
Data & | GetData (UpdateTrackerId update_tracker) |
const Data & | GetData (UpdateTrackerId update_tracker) const |
template<typename... Args> | |
UpdateTrackerId | NewUpdateTracker (Args &&... args) |
Manager the collection of update trackers for ModelStorage.
The Data type is the type of data associated with trackers.
This class makes sure it is possible to iterate on update trackers for ModelStorage modifications without having to hold a mutex. It does that by delaying additions & removals so that they are only applied when we need to iterate. This enables adding or removing trackers concurrently from multiple threads.
Definition at line 44 of file update_trackers.h.
using operations_research::math_opt::UpdateTrackers< Data >::IdDataPair = std::pair<UpdateTrackerId, std::unique_ptr<Data>> |
A pair (tracker_id, tracker_data).
Definition at line 47 of file update_trackers.h.
void operations_research::math_opt::UpdateTrackers< Data >::DeleteUpdateTracker | ( | UpdateTrackerId | update_tracker | ) |
Removes an update tracker.
The actual removal is delayed to the next call of GetUpdatedTrackers().
Thread-safety: this method is safe to be called from multiple threads at the same time. Since the update of vector returned by GetUpdatedTrackers() is delayed it is safe to iterate on it while this method is called.
Complexity: O(n), n is the number of trackers. The number of update trackers should be small, if it grows to a point where this is an issue this class can easily be made more efficient (O(lg n) or better).
The delete trackers may still be in pending_new_trackers_. We have to remove it from there.
The deleted trackers could already be in pending_removed_trackers_, which would be an issue since trackers can't be removed multiple times.
Test that the tracker actually exists.
Definition at line 195 of file update_trackers.h.
Data & operations_research::math_opt::UpdateTrackers< Data >::GetData | ( | UpdateTrackerId | update_tracker | ) |
Returns the data corresponding to the provided tracker. It CHECKs that the tracker exists.
It does not apply the pending actions (so that it can have a const overload), thus the result of GetUpdatedTrackers() is not modified.
Thread-safety: this method can be called from multiple threads but the resulting reference can be invalidated if the returned tracker is deleted and GetUpdatedTrackers() is called.
Complexity: O(n) where n is the number of trackers. The number of update trackers should be small, if it grows to a point where this is an issue this class can easily be made more efficient (O(lg n) or better).
The tracker may still be in pending_new_trackers_.
The tracker could be in pending_removed_trackers_.
The tracker must be in trackers_.
Definition at line 266 of file update_trackers.h.
const Data & operations_research::math_opt::UpdateTrackers< Data >::GetData | ( | UpdateTrackerId | update_tracker | ) | const |
The tracker may still be in pending_new_trackers_.
The tracker could be in pending_removed_trackers_.
The tracker must be in trackers_.
Definition at line 293 of file update_trackers.h.
const std::vector< typename UpdateTrackers< Data >::IdDataPair > & operations_research::math_opt::UpdateTrackers< Data >::GetUpdatedTrackers | ( | ) |
Apply pending additions/deletions and return the trackers.
Thread-safety: this method should not be called from multiple threads as the result is not protected by a mutex and thus could be change by the other call. Note though that concurrent calls to NewUpdateTracker() and DeleteUpdateTracker() are fine since the changes will only be applied on the next call to this function.
Here we use the "relaxed" memory order since we don't want or need to ensure proper ordering of memory accesses. We only want to make sure it is safe to delete a tracker from another thread while we read it here. Temporarily modifying a deleted tracker has no downside effect; we only care that the tracker will eventually be deleted, not that it is deleted as soon as possible.
Using a non-relaxed memory order has significant impact on performances here.
Flush removed trackers.
Move new trackers.
Definition at line 227 of file update_trackers.h.
UpdateTrackerId operations_research::math_opt::UpdateTrackers< Data >::NewUpdateTracker | ( | Args &&... | args | ) |
Definition at line 163 of file update_trackers.h.
UpdateTrackerId operations_research::math_opt::UpdateTrackers< Data >::NewUpdateTracker | ( | T &&... | args | ) |
Adds a new tracker. The args are forwarded to the constructor of the Data type.
The actual addition is delayed to the next call of GetUpdatedTrackers().
Thread-safety: this method is safe to be called from multiple threads at the same time.