blob: 401e9e9dea6d1c829fbb2b11e754658f6c56e48f [file] [log] [blame]
tome3489412014-08-29 02:30:38 -07001package org.onlab.graph;
2
3import com.google.common.collect.ImmutableList;
4
5import java.util.ArrayList;
6import java.util.List;
7import java.util.Objects;
8
tomeadbb462014-09-07 16:10:19 -07009import static com.google.common.base.MoreObjects.toStringHelper;
tome3489412014-08-29 02:30:38 -070010import static com.google.common.base.Preconditions.checkArgument;
11import static com.google.common.base.Preconditions.checkNotNull;
12
13/**
14 * Simple concrete implementation of a directed graph path.
15 */
16public class DefaultMutablePath<V extends Vertex, E extends Edge<V>> implements MutablePath<V, E> {
17
tome3489412014-08-29 02:30:38 -070018 private final List<E> edges = new ArrayList<>();
19 private double cost = 0.0;
20
21 /**
22 * Creates a new empty path.
23 */
24 public DefaultMutablePath() {
25 }
26
27 /**
28 * Creates a new path as a copy of another path.
29 *
30 * @param path path to be copied
31 */
32 public DefaultMutablePath(Path<V, E> path) {
33 checkNotNull(path, "Path cannot be null");
tome3489412014-08-29 02:30:38 -070034 this.cost = path.cost();
35 edges.addAll(path.edges());
36 }
37
38 @Override
39 public V src() {
tom144de692014-08-29 11:38:44 -070040 return edges.isEmpty() ? null : edges.get(0).src();
tome3489412014-08-29 02:30:38 -070041 }
42
43 @Override
44 public V dst() {
tom144de692014-08-29 11:38:44 -070045 return edges.isEmpty() ? null : edges.get(edges.size() - 1).dst();
tome3489412014-08-29 02:30:38 -070046 }
47
48 @Override
49 public double cost() {
50 return cost;
51 }
52
53 @Override
54 public List<E> edges() {
55 return ImmutableList.copyOf(edges);
56 }
57
58 @Override
59 public void setCost(double cost) {
60 this.cost = cost;
61 }
62
63 @Override
64 public Path<V, E> toImmutable() {
65 return new DefaultPath<>(edges, cost);
66 }
67
68 @Override
tom144de692014-08-29 11:38:44 -070069 public void insertEdge(E edge) {
70 checkNotNull(edge, "Edge cannot be null");
71 checkArgument(edges.isEmpty() || src().equals(edge.dst()),
72 "Edge destination must be the same as the current path source");
73 edges.add(0, edge);
74 }
75
76 @Override
tome3489412014-08-29 02:30:38 -070077 public void appendEdge(E edge) {
78 checkNotNull(edge, "Edge cannot be null");
tom144de692014-08-29 11:38:44 -070079 checkArgument(edges.isEmpty() || dst().equals(edge.src()),
tome3489412014-08-29 02:30:38 -070080 "Edge source must be the same as the current path destination");
tome3489412014-08-29 02:30:38 -070081 edges.add(edge);
82 }
83
84 @Override
tom144de692014-08-29 11:38:44 -070085 public void removeEdge(E edge) {
86 checkArgument(edge.src().equals(edge.dst()) ||
87 edges.indexOf(edge) == 0 ||
88 edges.lastIndexOf(edge) == edges.size() - 1,
89 "Edge must be at start or end of path, or it must be a cyclic edge");
90 edges.remove(edge);
tome3489412014-08-29 02:30:38 -070091 }
92
93 @Override
94 public String toString() {
tomeadbb462014-09-07 16:10:19 -070095 return toStringHelper(this)
tom144de692014-08-29 11:38:44 -070096 .add("src", src())
97 .add("dst", dst())
tome3489412014-08-29 02:30:38 -070098 .add("cost", cost)
99 .add("edges", edges)
100 .toString();
101 }
102
103 @Override
104 public int hashCode() {
tom144de692014-08-29 11:38:44 -0700105 return Objects.hash(edges, cost);
tome3489412014-08-29 02:30:38 -0700106 }
107
108 @Override
109 public boolean equals(Object obj) {
110 if (obj instanceof DefaultMutablePath) {
111 final DefaultMutablePath other = (DefaultMutablePath) obj;
tom144de692014-08-29 11:38:44 -0700112 return Objects.equals(this.cost, other.cost) &&
tome3489412014-08-29 02:30:38 -0700113 Objects.equals(this.edges, other.edges);
114 }
115 return false;
116 }
tom144de692014-08-29 11:38:44 -0700117
tome3489412014-08-29 02:30:38 -0700118}