-
Notifications
You must be signed in to change notification settings - Fork 4
Add counting on OD nodes #392
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,6 +49,8 @@ namespace dsf::mobility { | |
| std::unordered_map<Id, std::shared_ptr<Itinerary>> m_itineraries; | ||
| std::unordered_map<Id, double> m_originNodes; | ||
| std::unordered_map<Id, double> m_destinationNodes; | ||
| tbb::concurrent_unordered_map<Id, std::size_t> m_originCounts; | ||
| tbb::concurrent_unordered_map<Id, std::size_t> m_destinationCounts; | ||
| Size m_nAgents; | ||
|
|
||
| protected: | ||
|
|
@@ -327,6 +329,15 @@ namespace dsf::mobility { | |
| return m_turnMapping; | ||
| } | ||
|
|
||
| /// @brief Get the origin counts of the agents | ||
| /// @param bReset If true, the origin counts are cleared (default is true) | ||
| tbb::concurrent_unordered_map<Id, std::size_t> originCounts( | ||
| bool const bReset = true) noexcept; | ||
| /// @brief Get the destination counts of the agents | ||
| /// @param bReset If true, the destination counts are cleared (default is true) | ||
| tbb::concurrent_unordered_map<Id, std::size_t> destinationCounts( | ||
| bool const bReset = true) noexcept; | ||
|
|
||
| virtual double streetMeanSpeed(Id streetId) const; | ||
| virtual Measurement<double> streetMeanSpeed() const; | ||
| virtual Measurement<double> streetMeanSpeed(double, bool) const; | ||
|
|
@@ -453,6 +464,15 @@ namespace dsf::mobility { | |
| m_travelDTs.push_back({pAgent->distance(), | ||
| static_cast<double>(this->time_step() - pAgent->spawnTime())}); | ||
| --m_nAgents; | ||
| auto const& streetId = pAgent->streetId(); | ||
| if (streetId.has_value()) { | ||
| auto const& pStreet{this->graph().edge(streetId.value())}; | ||
| auto const& pNode{this->graph().node(pStreet->target())}; | ||
| auto [it, bInserted] = m_destinationCounts.insert({pNode->id(), 1}); | ||
| if (!bInserted) { | ||
| ++it->second; | ||
| } | ||
| } | ||
| return pAgent; | ||
| } | ||
|
|
||
|
|
@@ -1513,7 +1533,14 @@ namespace dsf::mobility { | |
| void RoadDynamics<delay_t>::addAgent(std::unique_ptr<Agent> pAgent) { | ||
| m_agents.push_back(std::move(pAgent)); | ||
| ++m_nAgents; | ||
| spdlog::debug("Added {}", *m_agents.back()); | ||
| spdlog::trace("Added {}", *m_agents.back()); | ||
| auto const& optNodeId{m_agents.back()->srcNodeId()}; | ||
| if (optNodeId.has_value()) { | ||
| auto [it, bInserted] = m_originCounts.insert({*optNodeId, 1}); | ||
| if (!bInserted) { | ||
| ++it->second; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| template <typename delay_t> | ||
|
|
@@ -2141,6 +2168,29 @@ namespace dsf::mobility { | |
| return normalizedTurnCounts; | ||
| } | ||
|
|
||
| template <typename delay_t> | ||
| requires(is_numeric_v<delay_t>) | ||
| tbb::concurrent_unordered_map<Id, std::size_t> RoadDynamics<delay_t>::originCounts( | ||
| bool const bReset) noexcept { | ||
| if (!bReset) { | ||
| return m_originCounts; | ||
| } | ||
| auto const tempCounts{std::move(m_originCounts)}; | ||
| m_originCounts.clear(); | ||
| return tempCounts; | ||
| } | ||
| template <typename delay_t> | ||
| requires(is_numeric_v<delay_t>) | ||
| tbb::concurrent_unordered_map<Id, std::size_t> RoadDynamics<delay_t>::destinationCounts( | ||
| bool const bReset) noexcept { | ||
| if (!bReset) { | ||
| return m_destinationCounts; | ||
| } | ||
| auto const tempCounts{std::move(m_destinationCounts)}; | ||
| m_destinationCounts.clear(); | ||
| return tempCounts; | ||
|
Comment on lines
+2186
to
+2191
|
||
| } | ||
|
Comment on lines
+2171
to
+2192
|
||
|
|
||
| template <typename delay_t> | ||
| requires(is_numeric_v<delay_t>) | ||
| double RoadDynamics<delay_t>::streetMeanSpeed(Id streetId) const { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The move-and-clear pattern for reset is not thread-safe when the map can be accessed concurrently. If reset=true, another thread could be incrementing values during the move operation or immediately after. Consider using a mutex to protect the reset operation, or document that these methods should only be called when no other threads are actively modifying the maps (e.g., between simulation steps).