diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index 8377e3c52..247c9cf4c 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -809,6 +809,8 @@ void local_clusters::clear () m_clusters.clear (); m_bbox = box_type (); m_next_dummy_id = 0; + m_soft_connections.clear (); + m_soft_connections_rev.clear (); } template @@ -846,6 +848,9 @@ local_clusters::remove_cluster (typename local_cluster::id_type id) local_cluster *to_delete = const_cast *> (& m_clusters.objects ().item (id - 1)); to_delete->clear (); m_needs_update = true; + + // take care of soft connections + remove_soft_connection_for (id); } template @@ -866,6 +871,10 @@ local_clusters::join_cluster_with (typename local_cluster::id_type id, typ // we just clear them. with->clear (); + // take care of soft connections + remove_soft_connection_for (id, with_id); + remove_soft_connection_for (with_id); + m_needs_update = true; } @@ -883,7 +892,81 @@ template void local_clusters::make_soft_connection (typename local_cluster::id_type a, typename local_cluster::id_type b) { - // @@@ TODO: implement + // NOTE: antiparallel connections are allowed. We will eliminate them later + + m_soft_connections [a].insert (b); + m_soft_connections_rev [b].insert (a); +} + +template +const std::set & +local_clusters::downward_soft_connections (typename local_cluster::id_type id) const +{ + static std::set empty; + + auto sc = m_soft_connections.find (id); + if (sc != m_soft_connections.end ()) { + return sc->second; + } else { + return empty; + } +} + +template +const std::set & +local_clusters::upward_soft_connections (typename local_cluster::id_type id) const +{ + static std::set empty; + + auto sc = m_soft_connections_rev.find (id); + if (sc != m_soft_connections_rev.end ()) { + return sc->second; + } else { + return empty; + } +} + +template +void +local_clusters::remove_soft_connection_for (typename local_cluster::id_type a, typename local_cluster::id_type b) +{ + auto sc = m_soft_connections.find (a); + if (sc != m_soft_connections.end ()) { + sc->second.erase (b); + if (sc->second.empty ()) { + m_soft_connections.erase (sc); + } + } + + sc = m_soft_connections_rev.find (b); + if (sc != m_soft_connections_rev.end ()) { + sc->second.erase (a); + if (sc->second.empty ()) { + m_soft_connections_rev.erase (sc); + } + } +} + +template +void +local_clusters::remove_soft_connection_for (typename local_cluster::id_type id) +{ + auto sc = m_soft_connections.find (id); + if (sc != m_soft_connections.end ()) { + + for (auto i = sc->second.begin (); i != sc->second.end (); ++i) { + auto sc_rev = m_soft_connections_rev.find (*i); + tl_assert (sc_rev != m_soft_connections_rev.end ()) { + sc_rev->second.erase (id); + if (sc_rev->second.empty ()) { + m_soft_connections_rev.erase (*i); + } + } + } + + m_soft_connections.erase (sc); + + } } template diff --git a/src/db/db/dbHierNetworkProcessor.h b/src/db/db/dbHierNetworkProcessor.h index 62b060644..4b5cb5679 100644 --- a/src/db/db/dbHierNetworkProcessor.h +++ b/src/db/db/dbHierNetworkProcessor.h @@ -627,6 +627,16 @@ public: */ void make_soft_connection (typename local_cluster::id_type a, typename local_cluster::id_type b); + /** + * @brief Get the downward soft connections for a given cluster + */ + const std::set &downward_soft_connections (typename local_cluster::id_type id) const; + + /** + * @brief Get the upward soft connections for a given cluster + */ + const std::set &upward_soft_connections (typename local_cluster::id_type id) const; + /** * @brief Gets the number of clusters */ @@ -647,8 +657,12 @@ private: box_type m_bbox; tree_type m_clusters; size_t m_next_dummy_id; + std::map > m_soft_connections; + std::map > m_soft_connections_rev; void apply_attr_equivalences (const tl::equivalence_clusters &attr_equivalence); + void remove_soft_connection_for (typename local_cluster::id_type a, typename local_cluster::id_type b); + void remove_soft_connection_for (typename local_cluster::id_type id); }; /**