@@ -23,59 +23,82 @@ type EdgeService struct {
2323// newDAG creates a new DAG (Directed Acyclic Graph) with initialized dependencies and dependents maps.
2424func newDAG () * DAG {
2525 return & DAG {
26- dependencies : new (sync.Map ),
27- dependents : new (sync.Map ),
26+ mu : sync.RWMutex {},
27+ dependencies : map [EdgeService ]map [EdgeService ]struct {}{},
28+ dependents : map [EdgeService ]map [EdgeService ]struct {}{},
2829 }
2930}
3031
3132// DAG represents a Directed Acyclic Graph of services, tracking dependencies and dependents.
3233type DAG struct {
33- dependencies * sync.Map
34- dependents * sync.Map
34+ mu sync.RWMutex
35+ dependencies map [EdgeService ]map [EdgeService ]struct {}
36+ dependents map [EdgeService ]map [EdgeService ]struct {}
3537}
3638
3739// addDependency adds a dependency relationship from one service to another in the DAG.
3840func (d * DAG ) addDependency (fromScopeID , fromScopeName , fromServiceName , toScopeID , toScopeName , toServiceName string ) {
3941 from := newEdgeService (fromScopeID , fromScopeName , fromServiceName )
4042 to := newEdgeService (toScopeID , toScopeName , toServiceName )
4143
42- d .addToMap (d .dependencies , from , to )
43- d .addToMap (d .dependents , to , from )
44+ d .mu .Lock ()
45+ defer d .mu .Unlock ()
46+
47+ // from -> to
48+ if _ , ok := d .dependencies [from ]; ! ok {
49+ d .dependencies [from ] = map [EdgeService ]struct {}{}
50+ }
51+ d.dependencies [from ][to ] = struct {}{}
52+
53+ // from <- to
54+ if _ , ok := d .dependents [to ]; ! ok {
55+ d .dependents [to ] = map [EdgeService ]struct {}{}
56+ }
57+ d.dependents [to ][from ] = struct {}{}
4458}
4559
46- // addToMap is a helper function to add a key-value pair to a sync.Map, creating a new sync.Map for the value if necessary.
47- func (d * DAG ) addToMap (dependencyMap * sync.Map , key , value interface {}) {
48- valueMap := new (sync.Map )
49- valueMap .Store (value , struct {}{})
60+ // removeService removes a dependency relationship between services in the DAG.
61+ func (d * DAG ) removeService (scopeID , scopeName , serviceName string ) {
62+ edge := newEdgeService (scopeID , scopeName , serviceName )
63+
64+ d .mu .Lock ()
65+ defer d .mu .Unlock ()
5066
51- if actual , loaded := dependencyMap .LoadOrStore (key , valueMap ); loaded {
52- actual .(* sync.Map ).Store (value , struct {}{})
67+ dependencies , dependents := d .explainServiceImplem (edge )
68+
69+ for _ , dependency := range dependencies {
70+ delete (d .dependents [dependency ], edge )
5371 }
72+
73+ // should be empty, because we remove dependencies in the inverse invocation order
74+ for _ , dependent := range dependents {
75+ delete (d .dependencies [dependent ], edge )
76+ }
77+
78+ delete (d .dependencies , edge )
79+ delete (d .dependents , edge )
5480}
5581
5682// explainService provides information about a service's dependencies and dependents in the DAG.
5783func (d * DAG ) explainService (scopeID , scopeName , serviceName string ) (dependencies , dependents []EdgeService ) {
5884 edge := newEdgeService (scopeID , scopeName , serviceName )
5985
60- dependencies = d . getServicesFromMap ( d . dependencies , edge )
61- dependents = d . getServicesFromMap ( d . dependents , edge )
86+ d . mu . RLock ( )
87+ defer d . mu . RUnlock ( )
6288
63- return dependencies , dependents
89+ return d . explainServiceImplem ( edge )
6490}
6591
66- // getServicesFromMap is a helper function to retrieve services related to a specific key from a sync.Map.
67- func (d * DAG ) getServicesFromMap (serviceMap * sync.Map , edge EdgeService ) []EdgeService {
68- var services []EdgeService
69-
70- if kv , ok := serviceMap .Load (edge ); ok {
71- kv .(* sync.Map ).Range (func (key , value interface {}) bool {
72- edgeService , ok := key .(EdgeService )
73- if ok {
74- services = append (services , edgeService )
75- }
76- return ok
77- })
92+ func (d * DAG ) explainServiceImplem (edge EdgeService ) (dependencies , dependents []EdgeService ) {
93+ dependencies , dependents = []EdgeService {}, []EdgeService {}
94+
95+ if kv , ok := d .dependencies [edge ]; ok {
96+ dependencies = keys (kv )
7897 }
7998
80- return services
99+ if kv , ok := d .dependents [edge ]; ok {
100+ dependents = keys (kv )
101+ }
102+
103+ return dependencies , dependents
81104}
0 commit comments