Showing
23 changed files
with
341 additions
and
370 deletions
... | @@ -16,7 +16,7 @@ public class DefaultLink extends AbstractModel implements Link { | ... | @@ -16,7 +16,7 @@ public class DefaultLink extends AbstractModel implements Link { |
16 | private final Type type; | 16 | private final Type type; |
17 | 17 | ||
18 | /** | 18 | /** |
19 | - * Creates a link description using the supplied information. | 19 | + * Creates an infrastructure link using the supplied information. |
20 | * | 20 | * |
21 | * @param providerId provider identity | 21 | * @param providerId provider identity |
22 | * @param src link source | 22 | * @param src link source | ... | ... |
1 | +package org.onlab.onos.net; | ||
2 | + | ||
3 | +import com.google.common.collect.ImmutableList; | ||
4 | +import org.onlab.onos.net.provider.ProviderId; | ||
5 | + | ||
6 | +import java.util.List; | ||
7 | +import java.util.Objects; | ||
8 | + | ||
9 | +import static com.google.common.base.Preconditions.checkArgument; | ||
10 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
11 | + | ||
12 | +/** | ||
13 | + * Default implementation of a network path. | ||
14 | + */ | ||
15 | +public class DefaultPath extends DefaultLink implements Path { | ||
16 | + | ||
17 | + private final List<Link> links; | ||
18 | + private final double cost; | ||
19 | + | ||
20 | + /** | ||
21 | + * Creates a path from the specified source and destination using the | ||
22 | + * supplied list of links. | ||
23 | + * | ||
24 | + * @param providerId provider identity | ||
25 | + * @param links contiguous links that comprise the path | ||
26 | + * @param cost unit-less path cost | ||
27 | + */ | ||
28 | + public DefaultPath(ProviderId providerId, List<Link> links, double cost) { | ||
29 | + super(providerId, source(links), destination(links), Type.INDIRECT); | ||
30 | + this.links = ImmutableList.copyOf(links); | ||
31 | + this.cost = cost; | ||
32 | + } | ||
33 | + | ||
34 | + @Override | ||
35 | + public List<Link> links() { | ||
36 | + return links; | ||
37 | + } | ||
38 | + | ||
39 | + @Override | ||
40 | + public double cost() { | ||
41 | + return cost; | ||
42 | + } | ||
43 | + | ||
44 | + // Returns the source of the first link. | ||
45 | + private static ConnectPoint source(List<Link> links) { | ||
46 | + checkNotNull(links, "List of path links cannot be null"); | ||
47 | + checkArgument(!links.isEmpty(), "List of path links cannot be empty"); | ||
48 | + return links.get(0).src(); | ||
49 | + } | ||
50 | + | ||
51 | + // Returns the destination of the last link. | ||
52 | + private static ConnectPoint destination(List<Link> links) { | ||
53 | + checkNotNull(links, "List of path links cannot be null"); | ||
54 | + checkArgument(!links.isEmpty(), "List of path links cannot be empty"); | ||
55 | + return links.get(links.size() - 1).dst(); | ||
56 | + } | ||
57 | + | ||
58 | + @Override | ||
59 | + public int hashCode() { | ||
60 | + return 31 * super.hashCode() + Objects.hash(links); | ||
61 | + } | ||
62 | + | ||
63 | + @Override | ||
64 | + public boolean equals(Object obj) { | ||
65 | + if (obj instanceof DefaultPath) { | ||
66 | + final DefaultPath other = (DefaultPath) obj; | ||
67 | + return Objects.equals(this.links, other.links); | ||
68 | + } | ||
69 | + return false; | ||
70 | + } | ||
71 | +} |
... | @@ -17,4 +17,11 @@ public interface Path extends Link { | ... | @@ -17,4 +17,11 @@ public interface Path extends Link { |
17 | */ | 17 | */ |
18 | List<Link> links(); | 18 | List<Link> links(); |
19 | 19 | ||
20 | + /** | ||
21 | + * Returns the path cost as a unit-less value. | ||
22 | + * | ||
23 | + * @return unit-less path cost | ||
24 | + */ | ||
25 | + double cost(); | ||
26 | + | ||
20 | } | 27 | } | ... | ... |
... | @@ -27,6 +27,15 @@ public final class ClusterId { | ... | @@ -27,6 +27,15 @@ public final class ClusterId { |
27 | return new ClusterId(id); | 27 | return new ClusterId(id); |
28 | } | 28 | } |
29 | 29 | ||
30 | + /** | ||
31 | + * Returns the backing integer index. | ||
32 | + * | ||
33 | + * @return backing integer index | ||
34 | + */ | ||
35 | + public int index() { | ||
36 | + return id; | ||
37 | + } | ||
38 | + | ||
30 | @Override | 39 | @Override |
31 | public int hashCode() { | 40 | public int hashCode() { |
32 | return Objects.hash(id); | 41 | return Objects.hash(id); | ... | ... |
1 | +package org.onlab.onos.net.topology; | ||
2 | + | ||
3 | +import com.google.common.collect.ImmutableSet; | ||
4 | +import org.onlab.onos.net.Description; | ||
5 | + | ||
6 | +/** | ||
7 | + * Describes attribute(s) of a network graph. | ||
8 | + */ | ||
9 | +public interface GraphDescription extends Description { | ||
10 | + | ||
11 | + /** | ||
12 | + * Returns the creation timestamp of the graph description. This is | ||
13 | + * expressed in system nanos to allow proper sequencing. | ||
14 | + * | ||
15 | + * @return graph description creation timestamp | ||
16 | + */ | ||
17 | + long timestamp(); | ||
18 | + | ||
19 | + /** | ||
20 | + * Returns the set of topology graph vertexes. | ||
21 | + * | ||
22 | + * @return set of graph vertexes | ||
23 | + */ | ||
24 | + ImmutableSet<TopologyVertex> vertexes(); | ||
25 | + | ||
26 | + /** | ||
27 | + * Returns the set of topology graph edges. | ||
28 | + * | ||
29 | + * @return set of graph edges | ||
30 | + */ | ||
31 | + ImmutableSet<TopologyEdge> edges(); | ||
32 | + | ||
33 | +} | ||
34 | + |
... | @@ -6,5 +6,5 @@ import org.onlab.graph.EdgeWeight; | ... | @@ -6,5 +6,5 @@ import org.onlab.graph.EdgeWeight; |
6 | * Entity capable of determining cost or weight of a specified topology | 6 | * Entity capable of determining cost or weight of a specified topology |
7 | * graph edge. | 7 | * graph edge. |
8 | */ | 8 | */ |
9 | -public interface LinkWeight extends EdgeWeight<TopoVertex, TopoEdge> { | 9 | +public interface LinkWeight extends EdgeWeight<TopologyVertex, TopologyEdge> { |
10 | } | 10 | } | ... | ... |
1 | -package org.onlab.onos.net.topology; | ||
2 | - | ||
3 | -import com.google.common.collect.ImmutableMap; | ||
4 | -import com.google.common.collect.ImmutableSet; | ||
5 | -import com.google.common.collect.ImmutableSetMultimap; | ||
6 | -import org.onlab.graph.Graph; | ||
7 | -import org.onlab.onos.net.Description; | ||
8 | -import org.onlab.onos.net.DeviceId; | ||
9 | -import org.onlab.onos.net.Link; | ||
10 | - | ||
11 | -import static org.onlab.graph.GraphPathSearch.Result; | ||
12 | - | ||
13 | -/** | ||
14 | - * Describes attribute(s) of a network topology. | ||
15 | - */ | ||
16 | -public interface TopologyDescription extends Description { | ||
17 | - | ||
18 | - /** | ||
19 | - * Returns the creation timestamp of the topology description. This is | ||
20 | - * expressed in system nanos to allow proper sequencing. | ||
21 | - * | ||
22 | - * @return topology description creation timestamp | ||
23 | - */ | ||
24 | - long timestamp(); | ||
25 | - | ||
26 | - /** | ||
27 | - * Returns the topology graph in immutable form. | ||
28 | - * | ||
29 | - * @return network graph | ||
30 | - */ | ||
31 | - Graph<TopoVertex, TopoEdge> graph(); | ||
32 | - | ||
33 | - /** | ||
34 | - * Returns an immutable map of path search results for each source device. | ||
35 | - * | ||
36 | - * @return map of path search result for each source node | ||
37 | - */ | ||
38 | - ImmutableMap<DeviceId, Result<TopoVertex, TopoEdge>> pathsBySource(); | ||
39 | - | ||
40 | - /** | ||
41 | - * Returns the set of topology SCC clusters. | ||
42 | - * | ||
43 | - * @return set of SCC clusters | ||
44 | - */ | ||
45 | - ImmutableSet<TopologyCluster> clusters(); | ||
46 | - | ||
47 | - /** | ||
48 | - * Returns an immutable set multi-map of devices for each cluster. | ||
49 | - * | ||
50 | - * @return set multi-map of devices that belong to each cluster | ||
51 | - */ | ||
52 | - ImmutableSetMultimap<TopologyCluster, DeviceId> devicesByCluster(); | ||
53 | - | ||
54 | - /** | ||
55 | - * Returns an immutable set multi-map of links for each cluster. | ||
56 | - * | ||
57 | - * @return set multi-map of links that belong to each cluster | ||
58 | - */ | ||
59 | - ImmutableSetMultimap<TopologyCluster, Link> linksByCluster(); | ||
60 | - | ||
61 | -} | ||
62 | - |
... | @@ -6,7 +6,7 @@ import org.onlab.onos.net.Link; | ... | @@ -6,7 +6,7 @@ import org.onlab.onos.net.Link; |
6 | /** | 6 | /** |
7 | * Represents an edge in the topology graph. | 7 | * Represents an edge in the topology graph. |
8 | */ | 8 | */ |
9 | -public interface TopoEdge extends Edge<TopoVertex> { | 9 | +public interface TopologyEdge extends Edge<TopologyVertex> { |
10 | 10 | ||
11 | /** | 11 | /** |
12 | * Returns the associated infrastructure link. | 12 | * Returns the associated infrastructure link. | ... | ... |
... | @@ -10,16 +10,13 @@ import java.util.List; | ... | @@ -10,16 +10,13 @@ import java.util.List; |
10 | */ | 10 | */ |
11 | public interface TopologyProviderService extends ProviderService<TopologyProvider> { | 11 | public interface TopologyProviderService extends ProviderService<TopologyProvider> { |
12 | 12 | ||
13 | - // What can be conveyed in a topology that isn't by individual | ||
14 | - // providers? | ||
15 | - | ||
16 | /** | 13 | /** |
17 | * Signals the core that some aspect of the topology has changed. | 14 | * Signals the core that some aspect of the topology has changed. |
18 | * | 15 | * |
19 | - * @param topoDescription information about topology | 16 | + * @param graphDescription information about the network graph |
20 | - * @param reasons events that triggered topology change | 17 | + * @param reasons events that triggered topology change |
21 | */ | 18 | */ |
22 | - void topologyChanged(TopologyDescription topoDescription, | 19 | + void topologyChanged(GraphDescription graphDescription, |
23 | List<Event> reasons); | 20 | List<Event> reasons); |
24 | 21 | ||
25 | } | 22 | } | ... | ... |
1 | package org.onlab.onos.net.topology; | 1 | package org.onlab.onos.net.topology; |
2 | 2 | ||
3 | -import org.onlab.graph.Graph; | ||
4 | import org.onlab.onos.net.ConnectPoint; | 3 | import org.onlab.onos.net.ConnectPoint; |
5 | import org.onlab.onos.net.DeviceId; | 4 | import org.onlab.onos.net.DeviceId; |
6 | import org.onlab.onos.net.Path; | 5 | import org.onlab.onos.net.Path; |
... | @@ -41,7 +40,7 @@ public interface TopologyService { | ... | @@ -41,7 +40,7 @@ public interface TopologyService { |
41 | * @param topology topology descriptor | 40 | * @param topology topology descriptor |
42 | * @return topology graph view | 41 | * @return topology graph view |
43 | */ | 42 | */ |
44 | - Graph<TopoVertex, TopoEdge> getGraph(Topology topology); | 43 | + TopologyGraph getGraph(Topology topology); |
45 | 44 | ||
46 | /** | 45 | /** |
47 | * Returns the set of all shortest paths, precomputed in terms of hop-count, | 46 | * Returns the set of all shortest paths, precomputed in terms of hop-count, | ... | ... |
... | @@ -6,7 +6,7 @@ import org.onlab.onos.net.DeviceId; | ... | @@ -6,7 +6,7 @@ import org.onlab.onos.net.DeviceId; |
6 | /** | 6 | /** |
7 | * Represents a vertex in the topology graph. | 7 | * Represents a vertex in the topology graph. |
8 | */ | 8 | */ |
9 | -public interface TopoVertex extends Vertex { | 9 | +public interface TopologyVertex extends Vertex { |
10 | 10 | ||
11 | /** | 11 | /** |
12 | * Returns the associated infrastructure device identification. | 12 | * Returns the associated infrastructure device identification. | ... | ... |
core/trivial/src/main/java/org/onlab/onos/net/trivial/topology/impl/DefaultGraphDescription.java
0 → 100644
1 | +package org.onlab.onos.net.trivial.topology.impl; | ||
2 | + | ||
3 | +import com.google.common.collect.ImmutableSet; | ||
4 | +import com.google.common.collect.Maps; | ||
5 | +import org.onlab.onos.net.ConnectPoint; | ||
6 | +import org.onlab.onos.net.Device; | ||
7 | +import org.onlab.onos.net.DeviceId; | ||
8 | +import org.onlab.onos.net.Link; | ||
9 | +import org.onlab.onos.net.topology.GraphDescription; | ||
10 | +import org.onlab.onos.net.topology.TopologyEdge; | ||
11 | +import org.onlab.onos.net.topology.TopologyVertex; | ||
12 | + | ||
13 | +import java.util.Map; | ||
14 | + | ||
15 | +/** | ||
16 | + * Default implementation of an immutable topology graph data carrier. | ||
17 | + */ | ||
18 | +class DefaultGraphDescription implements GraphDescription { | ||
19 | + | ||
20 | + private final long nanos; | ||
21 | + private final ImmutableSet<TopologyVertex> vertexes; | ||
22 | + private final ImmutableSet<TopologyEdge> edges; | ||
23 | + | ||
24 | + private final Map<DeviceId, TopologyVertex> vertexesById = Maps.newHashMap(); | ||
25 | + | ||
26 | + | ||
27 | + /** | ||
28 | + * Creates a minimal topology graph description to allow core to construct | ||
29 | + * and process the topology graph. | ||
30 | + * | ||
31 | + * @param nanos time in nanos of when the topology description was created | ||
32 | + * @param devices collection of infrastructure devices | ||
33 | + * @param links collection of infrastructure links | ||
34 | + */ | ||
35 | + DefaultGraphDescription(long nanos, Iterable<Device> devices, Iterable<Link> links) { | ||
36 | + this.nanos = nanos; | ||
37 | + this.vertexes = buildVertexes(devices); | ||
38 | + this.edges = buildEdges(links); | ||
39 | + vertexesById.clear(); | ||
40 | + } | ||
41 | + | ||
42 | + @Override | ||
43 | + public long timestamp() { | ||
44 | + return nanos; | ||
45 | + } | ||
46 | + | ||
47 | + @Override | ||
48 | + public ImmutableSet<TopologyVertex> vertexes() { | ||
49 | + return vertexes; | ||
50 | + } | ||
51 | + | ||
52 | + @Override | ||
53 | + public ImmutableSet<TopologyEdge> edges() { | ||
54 | + return edges; | ||
55 | + } | ||
56 | + | ||
57 | + // Builds a set of topology vertexes from the specified list of devices | ||
58 | + private ImmutableSet<TopologyVertex> buildVertexes(Iterable<Device> devices) { | ||
59 | + ImmutableSet.Builder<TopologyVertex> vertexes = ImmutableSet.builder(); | ||
60 | + for (Device device : devices) { | ||
61 | + TopologyVertex vertex = new DefaultTopologyVertex(device.id()); | ||
62 | + vertexes.add(vertex); | ||
63 | + vertexesById.put(vertex.deviceId(), vertex); | ||
64 | + } | ||
65 | + return vertexes.build(); | ||
66 | + } | ||
67 | + | ||
68 | + // Builds a set of topology vertexes from the specified list of links | ||
69 | + private ImmutableSet<TopologyEdge> buildEdges(Iterable<Link> links) { | ||
70 | + ImmutableSet.Builder<TopologyEdge> edges = ImmutableSet.builder(); | ||
71 | + for (Link link : links) { | ||
72 | + edges.add(new DefaultTopologyEdge(vertexOf(link.src()), | ||
73 | + vertexOf(link.dst()), link)); | ||
74 | + } | ||
75 | + return edges.build(); | ||
76 | + } | ||
77 | + | ||
78 | + // Fetches a vertex corresponding to the given connection point device. | ||
79 | + private TopologyVertex vertexOf(ConnectPoint connectPoint) { | ||
80 | + DeviceId id = connectPoint.deviceId(); | ||
81 | + TopologyVertex vertex = vertexesById.get(id); | ||
82 | + if (vertex == null) { | ||
83 | + // If vertex does not exist, create one and register it. | ||
84 | + vertex = new DefaultTopologyVertex(id); | ||
85 | + vertexesById.put(id, vertex); | ||
86 | + } | ||
87 | + return vertex; | ||
88 | + } | ||
89 | + | ||
90 | +} |
This diff is collapsed. Click to expand it.
1 | -package org.onlab.onos.net.trivial.topology.provider.impl; | 1 | +package org.onlab.onos.net.trivial.topology.impl; |
2 | 2 | ||
3 | import org.onlab.onos.net.Link; | 3 | import org.onlab.onos.net.Link; |
4 | -import org.onlab.onos.net.topology.TopoEdge; | 4 | +import org.onlab.onos.net.topology.TopologyEdge; |
5 | -import org.onlab.onos.net.topology.TopoVertex; | 5 | +import org.onlab.onos.net.topology.TopologyVertex; |
6 | 6 | ||
7 | import java.util.Objects; | 7 | import java.util.Objects; |
8 | 8 | ||
... | @@ -11,11 +11,11 @@ import static com.google.common.base.MoreObjects.toStringHelper; | ... | @@ -11,11 +11,11 @@ import static com.google.common.base.MoreObjects.toStringHelper; |
11 | /** | 11 | /** |
12 | * Implementation of the topology edge backed by a link. | 12 | * Implementation of the topology edge backed by a link. |
13 | */ | 13 | */ |
14 | -class DefaultTopoEdge implements TopoEdge { | 14 | +class DefaultTopologyEdge implements TopologyEdge { |
15 | 15 | ||
16 | private final Link link; | 16 | private final Link link; |
17 | - private final TopoVertex src; | 17 | + private final TopologyVertex src; |
18 | - private final TopoVertex dst; | 18 | + private final TopologyVertex dst; |
19 | 19 | ||
20 | /** | 20 | /** |
21 | * Creates a new topology edge. | 21 | * Creates a new topology edge. |
... | @@ -24,7 +24,7 @@ class DefaultTopoEdge implements TopoEdge { | ... | @@ -24,7 +24,7 @@ class DefaultTopoEdge implements TopoEdge { |
24 | * @param dst destination vertex | 24 | * @param dst destination vertex |
25 | * @param link infrastructure link | 25 | * @param link infrastructure link |
26 | */ | 26 | */ |
27 | - DefaultTopoEdge(TopoVertex src, TopoVertex dst, Link link) { | 27 | + DefaultTopologyEdge(TopologyVertex src, TopologyVertex dst, Link link) { |
28 | this.src = src; | 28 | this.src = src; |
29 | this.dst = dst; | 29 | this.dst = dst; |
30 | this.link = link; | 30 | this.link = link; |
... | @@ -36,12 +36,12 @@ class DefaultTopoEdge implements TopoEdge { | ... | @@ -36,12 +36,12 @@ class DefaultTopoEdge implements TopoEdge { |
36 | } | 36 | } |
37 | 37 | ||
38 | @Override | 38 | @Override |
39 | - public TopoVertex src() { | 39 | + public TopologyVertex src() { |
40 | return src; | 40 | return src; |
41 | } | 41 | } |
42 | 42 | ||
43 | @Override | 43 | @Override |
44 | - public TopoVertex dst() { | 44 | + public TopologyVertex dst() { |
45 | return dst; | 45 | return dst; |
46 | } | 46 | } |
47 | 47 | ||
... | @@ -52,8 +52,8 @@ class DefaultTopoEdge implements TopoEdge { | ... | @@ -52,8 +52,8 @@ class DefaultTopoEdge implements TopoEdge { |
52 | 52 | ||
53 | @Override | 53 | @Override |
54 | public boolean equals(Object obj) { | 54 | public boolean equals(Object obj) { |
55 | - if (obj instanceof DefaultTopoEdge) { | 55 | + if (obj instanceof DefaultTopologyEdge) { |
56 | - final DefaultTopoEdge other = (DefaultTopoEdge) obj; | 56 | + final DefaultTopologyEdge other = (DefaultTopologyEdge) obj; |
57 | return Objects.equals(this.link, other.link); | 57 | return Objects.equals(this.link, other.link); |
58 | } | 58 | } |
59 | return false; | 59 | return false; | ... | ... |
core/trivial/src/main/java/org/onlab/onos/net/trivial/topology/impl/DefaultTopologyGraph.java
0 → 100644
1 | +package org.onlab.onos.net.trivial.topology.impl; | ||
2 | + | ||
3 | +import org.onlab.graph.AdjacencyListsGraph; | ||
4 | +import org.onlab.onos.net.topology.TopologyEdge; | ||
5 | +import org.onlab.onos.net.topology.TopologyGraph; | ||
6 | +import org.onlab.onos.net.topology.TopologyVertex; | ||
7 | + | ||
8 | +import java.util.Set; | ||
9 | + | ||
10 | +/** | ||
11 | + * Default implementation of an immutable topology graph based on a generic | ||
12 | + * implementation of adjacency lists graph. | ||
13 | + */ | ||
14 | +public class DefaultTopologyGraph | ||
15 | + extends AdjacencyListsGraph<TopologyVertex, TopologyEdge> | ||
16 | + implements TopologyGraph { | ||
17 | + | ||
18 | + /** | ||
19 | + * Creates a topology graph comprising of the specified vertexes and edges. | ||
20 | + * | ||
21 | + * @param vertexes set of graph vertexes | ||
22 | + * @param edges set of graph edges | ||
23 | + */ | ||
24 | + public DefaultTopologyGraph(Set<TopologyVertex> vertexes, Set<TopologyEdge> edges) { | ||
25 | + super(vertexes, edges); | ||
26 | + } | ||
27 | + | ||
28 | +} |
1 | -package org.onlab.onos.net.trivial.topology.provider.impl; | 1 | +package org.onlab.onos.net.trivial.topology.impl; |
2 | 2 | ||
3 | import org.apache.felix.scr.annotations.Activate; | 3 | import org.apache.felix.scr.annotations.Activate; |
4 | import org.apache.felix.scr.annotations.Component; | 4 | import org.apache.felix.scr.annotations.Component; |
... | @@ -16,7 +16,7 @@ import org.onlab.onos.net.link.LinkListener; | ... | @@ -16,7 +16,7 @@ import org.onlab.onos.net.link.LinkListener; |
16 | import org.onlab.onos.net.link.LinkService; | 16 | import org.onlab.onos.net.link.LinkService; |
17 | import org.onlab.onos.net.provider.AbstractProvider; | 17 | import org.onlab.onos.net.provider.AbstractProvider; |
18 | import org.onlab.onos.net.provider.ProviderId; | 18 | import org.onlab.onos.net.provider.ProviderId; |
19 | -import org.onlab.onos.net.topology.TopologyDescription; | 19 | +import org.onlab.onos.net.topology.GraphDescription; |
20 | import org.onlab.onos.net.topology.TopologyProvider; | 20 | import org.onlab.onos.net.topology.TopologyProvider; |
21 | import org.onlab.onos.net.topology.TopologyProviderRegistry; | 21 | import org.onlab.onos.net.topology.TopologyProviderRegistry; |
22 | import org.onlab.onos.net.topology.TopologyProviderService; | 22 | import org.onlab.onos.net.topology.TopologyProviderService; |
... | @@ -35,7 +35,7 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -35,7 +35,7 @@ import static org.slf4j.LoggerFactory.getLogger; |
35 | * Simple implementation of a network topology provider/computor. | 35 | * Simple implementation of a network topology provider/computor. |
36 | */ | 36 | */ |
37 | @Component(immediate = true) | 37 | @Component(immediate = true) |
38 | -public class SimpleTopologyProvider extends AbstractProvider | 38 | +public class DefaultTopologyProvider extends AbstractProvider |
39 | implements TopologyProvider { | 39 | implements TopologyProvider { |
40 | 40 | ||
41 | // TODO: make these configurable | 41 | // TODO: make these configurable |
... | @@ -70,7 +70,7 @@ public class SimpleTopologyProvider extends AbstractProvider | ... | @@ -70,7 +70,7 @@ public class SimpleTopologyProvider extends AbstractProvider |
70 | /** | 70 | /** |
71 | * Creates a provider with the supplier identifier. | 71 | * Creates a provider with the supplier identifier. |
72 | */ | 72 | */ |
73 | - public SimpleTopologyProvider() { | 73 | + public DefaultTopologyProvider() { |
74 | super(new ProviderId("org.onlab.onos.provider.topology")); | 74 | super(new ProviderId("org.onlab.onos.provider.topology")); |
75 | } | 75 | } |
76 | 76 | ||
... | @@ -110,17 +110,19 @@ public class SimpleTopologyProvider extends AbstractProvider | ... | @@ -110,17 +110,19 @@ public class SimpleTopologyProvider extends AbstractProvider |
110 | * @param reasons events which triggered the topology change | 110 | * @param reasons events which triggered the topology change |
111 | */ | 111 | */ |
112 | private synchronized void triggerTopologyBuild(List<Event> reasons) { | 112 | private synchronized void triggerTopologyBuild(List<Event> reasons) { |
113 | - executor.execute(new TopologyBuilderTask(reasons)); | 113 | + if (executor != null) { |
114 | + executor.execute(new TopologyBuilderTask(reasons)); | ||
115 | + } | ||
114 | } | 116 | } |
115 | 117 | ||
116 | // Builds the topology using the latest device and link information | 118 | // Builds the topology using the latest device and link information |
117 | // and citing the specified events as reasons for the change. | 119 | // and citing the specified events as reasons for the change. |
118 | private void buildTopology(List<Event> reasons) { | 120 | private void buildTopology(List<Event> reasons) { |
119 | if (isStarted) { | 121 | if (isStarted) { |
120 | - TopologyDescription desc = | 122 | + GraphDescription desc = |
121 | - new DefaultTopologyDescription(System.nanoTime(), | 123 | + new DefaultGraphDescription(System.nanoTime(), |
122 | - deviceService.getDevices(), | 124 | + deviceService.getDevices(), |
123 | - linkService.getLinks()); | 125 | + linkService.getLinks()); |
124 | providerService.topologyChanged(desc, reasons); | 126 | providerService.topologyChanged(desc, reasons); |
125 | } | 127 | } |
126 | } | 128 | } | ... | ... |
1 | -package org.onlab.onos.net.trivial.topology.provider.impl; | 1 | +package org.onlab.onos.net.trivial.topology.impl; |
2 | 2 | ||
3 | import org.onlab.onos.net.DeviceId; | 3 | import org.onlab.onos.net.DeviceId; |
4 | -import org.onlab.onos.net.topology.TopoVertex; | 4 | +import org.onlab.onos.net.topology.TopologyVertex; |
5 | 5 | ||
6 | import java.util.Objects; | 6 | import java.util.Objects; |
7 | 7 | ||
8 | /** | 8 | /** |
9 | * Implementation of the topology vertex backed by a device id. | 9 | * Implementation of the topology vertex backed by a device id. |
10 | */ | 10 | */ |
11 | -class DefaultTopoVertex implements TopoVertex { | 11 | +class DefaultTopologyVertex implements TopologyVertex { |
12 | 12 | ||
13 | private final DeviceId deviceId; | 13 | private final DeviceId deviceId; |
14 | 14 | ||
... | @@ -17,7 +17,7 @@ class DefaultTopoVertex implements TopoVertex { | ... | @@ -17,7 +17,7 @@ class DefaultTopoVertex implements TopoVertex { |
17 | * | 17 | * |
18 | * @param deviceId backing infrastructure device identifier | 18 | * @param deviceId backing infrastructure device identifier |
19 | */ | 19 | */ |
20 | - DefaultTopoVertex(DeviceId deviceId) { | 20 | + DefaultTopologyVertex(DeviceId deviceId) { |
21 | this.deviceId = deviceId; | 21 | this.deviceId = deviceId; |
22 | } | 22 | } |
23 | 23 | ||
... | @@ -33,8 +33,8 @@ class DefaultTopoVertex implements TopoVertex { | ... | @@ -33,8 +33,8 @@ class DefaultTopoVertex implements TopoVertex { |
33 | 33 | ||
34 | @Override | 34 | @Override |
35 | public boolean equals(Object obj) { | 35 | public boolean equals(Object obj) { |
36 | - if (obj instanceof DefaultTopoVertex) { | 36 | + if (obj instanceof DefaultTopologyVertex) { |
37 | - final DefaultTopoVertex other = (DefaultTopoVertex) obj; | 37 | + final DefaultTopologyVertex other = (DefaultTopologyVertex) obj; |
38 | return Objects.equals(this.deviceId, other.deviceId); | 38 | return Objects.equals(this.deviceId, other.deviceId); |
39 | } | 39 | } |
40 | return false; | 40 | return false; | ... | ... |
1 | +package org.onlab.onos.net.trivial.topology.impl; | ||
2 | + | ||
3 | +import org.onlab.onos.net.DeviceId; | ||
4 | + | ||
5 | +import java.util.Objects; | ||
6 | + | ||
7 | +/** | ||
8 | + * Key for filing src/dst paths. | ||
9 | + */ | ||
10 | +class PathKey { | ||
11 | + private final DeviceId src; | ||
12 | + private final DeviceId dst; | ||
13 | + | ||
14 | + /** | ||
15 | + * Creates a path key from the given source/dest pair. | ||
16 | + * @param src source device | ||
17 | + * @param dst destination device | ||
18 | + */ | ||
19 | + PathKey(DeviceId src, DeviceId dst) { | ||
20 | + this.src = src; | ||
21 | + this.dst = dst; | ||
22 | + } | ||
23 | + | ||
24 | + @Override | ||
25 | + public int hashCode() { | ||
26 | + return Objects.hash(src, dst); | ||
27 | + } | ||
28 | + | ||
29 | + @Override | ||
30 | + public boolean equals(Object obj) { | ||
31 | + if (obj instanceof PathKey) { | ||
32 | + final PathKey other = (PathKey) obj; | ||
33 | + return Objects.equals(this.src, other.src) && Objects.equals(this.dst, other.dst); | ||
34 | + } | ||
35 | + return false; | ||
36 | + } | ||
37 | +} |
... | @@ -6,7 +6,6 @@ import org.apache.felix.scr.annotations.Deactivate; | ... | @@ -6,7 +6,6 @@ import org.apache.felix.scr.annotations.Deactivate; |
6 | import org.apache.felix.scr.annotations.Reference; | 6 | import org.apache.felix.scr.annotations.Reference; |
7 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 7 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
8 | import org.apache.felix.scr.annotations.Service; | 8 | import org.apache.felix.scr.annotations.Service; |
9 | -import org.onlab.graph.Graph; | ||
10 | import org.onlab.onos.event.AbstractListenerRegistry; | 9 | import org.onlab.onos.event.AbstractListenerRegistry; |
11 | import org.onlab.onos.event.Event; | 10 | import org.onlab.onos.event.Event; |
12 | import org.onlab.onos.event.EventDeliveryService; | 11 | import org.onlab.onos.event.EventDeliveryService; |
... | @@ -15,13 +14,12 @@ import org.onlab.onos.net.DeviceId; | ... | @@ -15,13 +14,12 @@ import org.onlab.onos.net.DeviceId; |
15 | import org.onlab.onos.net.Path; | 14 | import org.onlab.onos.net.Path; |
16 | import org.onlab.onos.net.provider.AbstractProviderRegistry; | 15 | import org.onlab.onos.net.provider.AbstractProviderRegistry; |
17 | import org.onlab.onos.net.provider.AbstractProviderService; | 16 | import org.onlab.onos.net.provider.AbstractProviderService; |
17 | +import org.onlab.onos.net.topology.GraphDescription; | ||
18 | import org.onlab.onos.net.topology.LinkWeight; | 18 | import org.onlab.onos.net.topology.LinkWeight; |
19 | -import org.onlab.onos.net.topology.TopoEdge; | ||
20 | -import org.onlab.onos.net.topology.TopoVertex; | ||
21 | import org.onlab.onos.net.topology.Topology; | 19 | import org.onlab.onos.net.topology.Topology; |
22 | import org.onlab.onos.net.topology.TopologyCluster; | 20 | import org.onlab.onos.net.topology.TopologyCluster; |
23 | -import org.onlab.onos.net.topology.TopologyDescription; | ||
24 | import org.onlab.onos.net.topology.TopologyEvent; | 21 | import org.onlab.onos.net.topology.TopologyEvent; |
22 | +import org.onlab.onos.net.topology.TopologyGraph; | ||
25 | import org.onlab.onos.net.topology.TopologyListener; | 23 | import org.onlab.onos.net.topology.TopologyListener; |
26 | import org.onlab.onos.net.topology.TopologyProvider; | 24 | import org.onlab.onos.net.topology.TopologyProvider; |
27 | import org.onlab.onos.net.topology.TopologyProviderRegistry; | 25 | import org.onlab.onos.net.topology.TopologyProviderRegistry; |
... | @@ -98,7 +96,7 @@ public class SimpleTopologyManager | ... | @@ -98,7 +96,7 @@ public class SimpleTopologyManager |
98 | } | 96 | } |
99 | 97 | ||
100 | @Override | 98 | @Override |
101 | - public Graph<TopoVertex, TopoEdge> getGraph(Topology topology) { | 99 | + public TopologyGraph getGraph(Topology topology) { |
102 | checkNotNull(topology, TOPOLOGY_NULL); | 100 | checkNotNull(topology, TOPOLOGY_NULL); |
103 | return store.getGraph(defaultTopology(topology)); | 101 | return store.getGraph(defaultTopology(topology)); |
104 | } | 102 | } |
... | @@ -159,16 +157,14 @@ public class SimpleTopologyManager | ... | @@ -159,16 +157,14 @@ public class SimpleTopologyManager |
159 | } | 157 | } |
160 | 158 | ||
161 | @Override | 159 | @Override |
162 | - public void topologyChanged(TopologyDescription topoDescription, | 160 | + public void topologyChanged(GraphDescription topoDescription, |
163 | List<Event> reasons) { | 161 | List<Event> reasons) { |
164 | checkNotNull(topoDescription, "Topology description cannot be null"); | 162 | checkNotNull(topoDescription, "Topology description cannot be null"); |
165 | 163 | ||
166 | - log.info("Topology changed due to: {}", // to be removed soon | ||
167 | - reasons == null ? "initial compute" : reasons); | ||
168 | TopologyEvent event = store.updateTopology(provider().id(), | 164 | TopologyEvent event = store.updateTopology(provider().id(), |
169 | topoDescription, reasons); | 165 | topoDescription, reasons); |
170 | if (event != null) { | 166 | if (event != null) { |
171 | - log.info("Topology changed due to: {}", | 167 | + log.info("Topology {} changed due to: {}", event.subject(), |
172 | reasons == null ? "initial compute" : reasons); | 168 | reasons == null ? "initial compute" : reasons); |
173 | eventDispatcher.post(event); | 169 | eventDispatcher.post(event); |
174 | } | 170 | } | ... | ... |
1 | package org.onlab.onos.net.trivial.topology.impl; | 1 | package org.onlab.onos.net.trivial.topology.impl; |
2 | 2 | ||
3 | -import org.onlab.graph.Graph; | ||
4 | import org.onlab.onos.event.Event; | 3 | import org.onlab.onos.event.Event; |
5 | import org.onlab.onos.net.ConnectPoint; | 4 | import org.onlab.onos.net.ConnectPoint; |
6 | import org.onlab.onos.net.DeviceId; | 5 | import org.onlab.onos.net.DeviceId; |
7 | import org.onlab.onos.net.Path; | 6 | import org.onlab.onos.net.Path; |
8 | import org.onlab.onos.net.provider.ProviderId; | 7 | import org.onlab.onos.net.provider.ProviderId; |
8 | +import org.onlab.onos.net.topology.GraphDescription; | ||
9 | import org.onlab.onos.net.topology.LinkWeight; | 9 | import org.onlab.onos.net.topology.LinkWeight; |
10 | -import org.onlab.onos.net.topology.TopoEdge; | ||
11 | -import org.onlab.onos.net.topology.TopoVertex; | ||
12 | import org.onlab.onos.net.topology.Topology; | 10 | import org.onlab.onos.net.topology.Topology; |
13 | import org.onlab.onos.net.topology.TopologyCluster; | 11 | import org.onlab.onos.net.topology.TopologyCluster; |
14 | -import org.onlab.onos.net.topology.TopologyDescription; | ||
15 | import org.onlab.onos.net.topology.TopologyEvent; | 12 | import org.onlab.onos.net.topology.TopologyEvent; |
13 | +import org.onlab.onos.net.topology.TopologyGraph; | ||
16 | 14 | ||
17 | import java.util.List; | 15 | import java.util.List; |
18 | import java.util.Set; | 16 | import java.util.Set; |
... | @@ -61,7 +59,7 @@ class SimpleTopologyStore { | ... | @@ -61,7 +59,7 @@ class SimpleTopologyStore { |
61 | * @param topology topology descriptor | 59 | * @param topology topology descriptor |
62 | * @return graph view | 60 | * @return graph view |
63 | */ | 61 | */ |
64 | - Graph<TopoVertex, TopoEdge> getGraph(DefaultTopology topology) { | 62 | + TopologyGraph getGraph(DefaultTopology topology) { |
65 | return topology.getGraph(); | 63 | return topology.getGraph(); |
66 | } | 64 | } |
67 | 65 | ||
... | @@ -88,7 +86,7 @@ class SimpleTopologyStore { | ... | @@ -88,7 +86,7 @@ class SimpleTopologyStore { |
88 | */ | 86 | */ |
89 | Set<Path> getPaths(DefaultTopology topology, DeviceId src, DeviceId dst, | 87 | Set<Path> getPaths(DefaultTopology topology, DeviceId src, DeviceId dst, |
90 | LinkWeight weight) { | 88 | LinkWeight weight) { |
91 | - return null; | 89 | + return topology.getPaths(src, dst, weight); |
92 | } | 90 | } |
93 | 91 | ||
94 | /** | 92 | /** |
... | @@ -116,27 +114,29 @@ class SimpleTopologyStore { | ... | @@ -116,27 +114,29 @@ class SimpleTopologyStore { |
116 | /** | 114 | /** |
117 | * Generates a new topology snapshot from the specified description. | 115 | * Generates a new topology snapshot from the specified description. |
118 | * | 116 | * |
119 | - * @param providerId provider identification | 117 | + * @param providerId provider identification |
120 | - * @param topoDescription topology description | 118 | + * @param graphDescription topology graph description |
121 | - * @param reasons list of events that triggered the update | 119 | + * @param reasons list of events that triggered the update |
122 | * @return topology update event or null if the description is old | 120 | * @return topology update event or null if the description is old |
123 | */ | 121 | */ |
124 | TopologyEvent updateTopology(ProviderId providerId, | 122 | TopologyEvent updateTopology(ProviderId providerId, |
125 | - TopologyDescription topoDescription, | 123 | + GraphDescription graphDescription, |
126 | List<Event> reasons) { | 124 | List<Event> reasons) { |
127 | // First off, make sure that what we're given is indeed newer than | 125 | // First off, make sure that what we're given is indeed newer than |
128 | // what we already have. | 126 | // what we already have. |
129 | - if (current != null && topoDescription.timestamp() < current.time()) { | 127 | + if (current != null && graphDescription.timestamp() < current.time()) { |
130 | return null; | 128 | return null; |
131 | } | 129 | } |
132 | 130 | ||
133 | // Have the default topology construct self from the description data. | 131 | // Have the default topology construct self from the description data. |
134 | DefaultTopology newTopology = | 132 | DefaultTopology newTopology = |
135 | - new DefaultTopology(providerId, topoDescription); | 133 | + new DefaultTopology(providerId, graphDescription); |
136 | 134 | ||
137 | // Promote the new topology to current and return a ready-to-send event. | 135 | // Promote the new topology to current and return a ready-to-send event. |
138 | - current = newTopology; | 136 | + synchronized (this) { |
139 | - return new TopologyEvent(TopologyEvent.Type.TOPOLOGY_CHANGED, current); | 137 | + current = newTopology; |
138 | + return new TopologyEvent(TopologyEvent.Type.TOPOLOGY_CHANGED, current); | ||
139 | + } | ||
140 | } | 140 | } |
141 | 141 | ||
142 | } | 142 | } | ... | ... |
1 | -package org.onlab.onos.net.trivial.topology.provider.impl; | ||
2 | - | ||
3 | -import com.google.common.collect.ImmutableMap; | ||
4 | -import com.google.common.collect.ImmutableSet; | ||
5 | -import com.google.common.collect.ImmutableSetMultimap; | ||
6 | -import com.google.common.collect.Maps; | ||
7 | -import com.google.common.collect.Sets; | ||
8 | -import org.onlab.graph.AdjacencyListsGraph; | ||
9 | -import org.onlab.graph.DijkstraGraphSearch; | ||
10 | -import org.onlab.graph.Graph; | ||
11 | -import org.onlab.graph.GraphPathSearch; | ||
12 | -import org.onlab.graph.TarjanGraphSearch; | ||
13 | -import org.onlab.onos.net.ConnectPoint; | ||
14 | -import org.onlab.onos.net.Device; | ||
15 | -import org.onlab.onos.net.DeviceId; | ||
16 | -import org.onlab.onos.net.Link; | ||
17 | -import org.onlab.onos.net.topology.ClusterId; | ||
18 | -import org.onlab.onos.net.topology.DefaultTopologyCluster; | ||
19 | -import org.onlab.onos.net.topology.LinkWeight; | ||
20 | -import org.onlab.onos.net.topology.TopoEdge; | ||
21 | -import org.onlab.onos.net.topology.TopoVertex; | ||
22 | -import org.onlab.onos.net.topology.TopologyCluster; | ||
23 | -import org.onlab.onos.net.topology.TopologyDescription; | ||
24 | - | ||
25 | -import java.util.List; | ||
26 | -import java.util.Map; | ||
27 | -import java.util.Set; | ||
28 | - | ||
29 | -import static com.google.common.collect.ImmutableSetMultimap.Builder; | ||
30 | -import static com.google.common.collect.ImmutableSetMultimap.builder; | ||
31 | -import static org.onlab.graph.GraphPathSearch.Result; | ||
32 | -import static org.onlab.graph.TarjanGraphSearch.SCCResult; | ||
33 | -import static org.onlab.onos.net.Link.Type.INDIRECT; | ||
34 | - | ||
35 | -/** | ||
36 | - * Default implementation of an immutable topology data carrier. | ||
37 | - */ | ||
38 | -class DefaultTopologyDescription implements TopologyDescription { | ||
39 | - | ||
40 | - private static final GraphPathSearch<TopoVertex, TopoEdge> DIJKSTRA = | ||
41 | - new DijkstraGraphSearch<>(); | ||
42 | - private static final TarjanGraphSearch<TopoVertex, TopoEdge> TARJAN = | ||
43 | - new TarjanGraphSearch<>(); | ||
44 | - | ||
45 | - private final long nanos; | ||
46 | - private final Map<DeviceId, TopoVertex> vertexesById = Maps.newHashMap(); | ||
47 | - private final Graph<TopoVertex, TopoEdge> graph; | ||
48 | - private final ImmutableMap<DeviceId, Result<TopoVertex, TopoEdge>> results; | ||
49 | - | ||
50 | - // Cluster-related structures | ||
51 | - private final ImmutableSet<TopologyCluster> clusters; | ||
52 | - private ImmutableSetMultimap<TopologyCluster, DeviceId> devicesByCluster; | ||
53 | - private ImmutableSetMultimap<TopologyCluster, Link> linksByCluster; | ||
54 | - | ||
55 | - /** | ||
56 | - * Creates a topology description to carry topology vitals to the core. | ||
57 | - * | ||
58 | - * @param nanos time in nanos of when the topology description was created | ||
59 | - * @param devices collection of infrastructure devices | ||
60 | - * @param links collection of infrastructure links | ||
61 | - */ | ||
62 | - DefaultTopologyDescription(long nanos, Iterable<Device> devices, Iterable<Link> links) { | ||
63 | - this.nanos = nanos; | ||
64 | - this.graph = buildGraph(devices, links); | ||
65 | - this.results = computeDefaultPaths(); | ||
66 | - this.clusters = computeClusters(); | ||
67 | - } | ||
68 | - | ||
69 | - @Override | ||
70 | - public long timestamp() { | ||
71 | - return nanos; | ||
72 | - } | ||
73 | - | ||
74 | - @Override | ||
75 | - public Graph<TopoVertex, TopoEdge> graph() { | ||
76 | - return graph; | ||
77 | - } | ||
78 | - | ||
79 | - @Override | ||
80 | - public ImmutableMap<DeviceId, Result<TopoVertex, TopoEdge>> pathsBySource() { | ||
81 | - return results; | ||
82 | - } | ||
83 | - | ||
84 | - @Override | ||
85 | - public ImmutableSet<TopologyCluster> clusters() { | ||
86 | - return clusters; | ||
87 | - } | ||
88 | - | ||
89 | - @Override | ||
90 | - public ImmutableSetMultimap<TopologyCluster, DeviceId> devicesByCluster() { | ||
91 | - return devicesByCluster; | ||
92 | - } | ||
93 | - | ||
94 | - @Override | ||
95 | - public ImmutableSetMultimap<TopologyCluster, Link> linksByCluster() { | ||
96 | - return linksByCluster; | ||
97 | - } | ||
98 | - | ||
99 | - // Link weight for measuring link cost as hop count with indirect links | ||
100 | - // being as expensive as traversing the entire graph to assume the worst. | ||
101 | - private static class HopCountLinkWeight implements LinkWeight { | ||
102 | - private final int indirectLinkCost; | ||
103 | - | ||
104 | - HopCountLinkWeight(int indirectLinkCost) { | ||
105 | - this.indirectLinkCost = indirectLinkCost; | ||
106 | - } | ||
107 | - | ||
108 | - @Override | ||
109 | - public double weight(TopoEdge edge) { | ||
110 | - // To force preference to use direct paths first, make indirect | ||
111 | - // links as expensive as the linear vertex traversal. | ||
112 | - return edge.link().type() == INDIRECT ? indirectLinkCost : 1; | ||
113 | - } | ||
114 | - } | ||
115 | - | ||
116 | - // Link weight for preventing traversal over indirect links. | ||
117 | - private static class NoIndirectLinksWeight implements LinkWeight { | ||
118 | - @Override | ||
119 | - public double weight(TopoEdge edge) { | ||
120 | - return edge.link().type() == INDIRECT ? -1 : 1; | ||
121 | - } | ||
122 | - } | ||
123 | - | ||
124 | - // Constructs the topology graph using the supplied devices and links. | ||
125 | - private Graph<TopoVertex, TopoEdge> buildGraph(Iterable<Device> devices, | ||
126 | - Iterable<Link> links) { | ||
127 | - return new AdjacencyListsGraph<>(buildVertexes(devices), | ||
128 | - buildEdges(links)); | ||
129 | - } | ||
130 | - | ||
131 | - // Builds a set of topology vertexes from the specified list of devices | ||
132 | - private Set<TopoVertex> buildVertexes(Iterable<Device> devices) { | ||
133 | - Set<TopoVertex> vertexes = Sets.newHashSet(); | ||
134 | - for (Device device : devices) { | ||
135 | - TopoVertex vertex = new DefaultTopoVertex(device.id()); | ||
136 | - vertexes.add(vertex); | ||
137 | - vertexesById.put(vertex.deviceId(), vertex); | ||
138 | - } | ||
139 | - return vertexes; | ||
140 | - } | ||
141 | - | ||
142 | - // Builds a set of topology vertexes from the specified list of links | ||
143 | - private Set<TopoEdge> buildEdges(Iterable<Link> links) { | ||
144 | - Set<TopoEdge> edges = Sets.newHashSet(); | ||
145 | - for (Link link : links) { | ||
146 | - edges.add(new DefaultTopoEdge(vertexOf(link.src()), | ||
147 | - vertexOf(link.dst()), link)); | ||
148 | - } | ||
149 | - return edges; | ||
150 | - } | ||
151 | - | ||
152 | - // Computes the default shortest paths for all source/dest pairs using | ||
153 | - // the multi-path Dijkstra and hop-count as path cost. | ||
154 | - private ImmutableMap<DeviceId, Result<TopoVertex, TopoEdge>> computeDefaultPaths() { | ||
155 | - LinkWeight weight = new HopCountLinkWeight(graph.getVertexes().size()); | ||
156 | - ImmutableMap.Builder<DeviceId, Result<TopoVertex, TopoEdge>> results = | ||
157 | - ImmutableMap.builder(); | ||
158 | - | ||
159 | - // Search graph paths for each source to all destinations. | ||
160 | - for (TopoVertex src : vertexesById.values()) { | ||
161 | - results.put(src.deviceId(), DIJKSTRA.search(graph, src, null, weight)); | ||
162 | - } | ||
163 | - return results.build(); | ||
164 | - } | ||
165 | - | ||
166 | - // Computes topology SCC clusters using Tarjan algorithm. | ||
167 | - private ImmutableSet<TopologyCluster> computeClusters() { | ||
168 | - ImmutableSet.Builder<TopologyCluster> clusterBuilder = ImmutableSet.builder(); | ||
169 | - SCCResult<TopoVertex, TopoEdge> result = | ||
170 | - TARJAN.search(graph, new NoIndirectLinksWeight()); | ||
171 | - | ||
172 | - // Extract both vertexes and edges from the results; the lists form | ||
173 | - // pairs along the same index. | ||
174 | - List<Set<TopoVertex>> clusterVertexes = result.clusterVertexes(); | ||
175 | - List<Set<TopoEdge>> clusterEdges = result.clusterEdges(); | ||
176 | - | ||
177 | - Builder<TopologyCluster, DeviceId> devicesBuilder = ImmutableSetMultimap.builder(); | ||
178 | - Builder<TopologyCluster, Link> linksBuilder = ImmutableSetMultimap.builder(); | ||
179 | - | ||
180 | - // Scan over the lists and create a cluster from the results. | ||
181 | - for (int i = 0, n = result.clusterCount(); i < n; i++) { | ||
182 | - Set<TopoVertex> vertexSet = clusterVertexes.get(i); | ||
183 | - Set<TopoEdge> edgeSet = clusterEdges.get(i); | ||
184 | - | ||
185 | - DefaultTopologyCluster cluster = | ||
186 | - new DefaultTopologyCluster(ClusterId.clusterId(i), | ||
187 | - vertexSet.size(), edgeSet.size(), | ||
188 | - findRoot(vertexSet).deviceId()); | ||
189 | - clusterBuilder.add(cluster); | ||
190 | - findClusterDevices(vertexSet, cluster, devicesBuilder); | ||
191 | - findClusterLinks(edgeSet, cluster, linksBuilder); | ||
192 | - } | ||
193 | - return clusterBuilder.build(); | ||
194 | - } | ||
195 | - | ||
196 | - // Scans through the set of cluster vertexes and puts their devices in a | ||
197 | - // multi-map associated with the cluster. It also binds the devices to | ||
198 | - // the cluster. | ||
199 | - private void findClusterDevices(Set<TopoVertex> vertexSet, | ||
200 | - DefaultTopologyCluster cluster, | ||
201 | - Builder<TopologyCluster, DeviceId> builder) { | ||
202 | - for (TopoVertex vertex : vertexSet) { | ||
203 | - DeviceId deviceId = vertex.deviceId(); | ||
204 | - builder.put(cluster, deviceId); | ||
205 | - } | ||
206 | - } | ||
207 | - | ||
208 | - // Scans through the set of cluster edges and puts their links in a | ||
209 | - // multi-map associated with the cluster. | ||
210 | - private void findClusterLinks(Set<TopoEdge> edgeSet, | ||
211 | - DefaultTopologyCluster cluster, | ||
212 | - Builder<TopologyCluster, Link> builder) { | ||
213 | - for (TopoEdge edge : edgeSet) { | ||
214 | - builder.put(cluster, edge.link()); | ||
215 | - } | ||
216 | - } | ||
217 | - | ||
218 | - // Finds the vertex whose device id is the lexicographical minimum in the | ||
219 | - // specified set. | ||
220 | - private TopoVertex findRoot(Set<TopoVertex> vertexSet) { | ||
221 | - TopoVertex minVertex = null; | ||
222 | - for (TopoVertex vertex : vertexSet) { | ||
223 | - if (minVertex == null || | ||
224 | - minVertex.deviceId().toString() | ||
225 | - .compareTo(minVertex.deviceId().toString()) < 0) { | ||
226 | - minVertex = vertex; | ||
227 | - } | ||
228 | - } | ||
229 | - return minVertex; | ||
230 | - } | ||
231 | - | ||
232 | - // Fetches a vertex corresponding to the given connection point device. | ||
233 | - private TopoVertex vertexOf(ConnectPoint connectPoint) { | ||
234 | - DeviceId id = connectPoint.deviceId(); | ||
235 | - TopoVertex vertex = vertexesById.get(id); | ||
236 | - if (vertex == null) { | ||
237 | - // If vertex does not exist, create one and register it. | ||
238 | - vertex = new DefaultTopoVertex(id); | ||
239 | - vertexesById.put(id, vertex); | ||
240 | - } | ||
241 | - return vertex; | ||
242 | - } | ||
243 | - | ||
244 | -} |
-
Please register or login to post a comment