blob: be7ad180c2ef63c79b191405ca543ccf4ca937d9 [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
9import static com.google.common.base.Preconditions.checkArgument;
10import static com.google.common.base.Preconditions.checkNotNull;
11
12/**
13 * Simple concrete implementation of a directed graph path.
14 */
15public class DefaultMutablePath<V extends Vertex, E extends Edge<V>> implements MutablePath<V, E> {
16
tome3489412014-08-29 02:30:38 -070017 private final List<E> edges = new ArrayList<>();
18 private double cost = 0.0;
19
20 /**
21 * Creates a new empty path.
22 */
23 public DefaultMutablePath() {
24 }
25
26 /**
27 * Creates a new path as a copy of another path.
28 *
29 * @param path path to be copied
30 */
31 public DefaultMutablePath(Path<V, E> path) {
32 checkNotNull(path, "Path cannot be null");
tome3489412014-08-29 02:30:38 -070033 this.cost = path.cost();
34 edges.addAll(path.edges());
35 }
36
37 @Override
38 public V src() {
tom144de692014-08-29 11:38:44 -070039 return edges.isEmpty() ? null : edges.get(0).src();
tome3489412014-08-29 02:30:38 -070040 }
41
42 @Override
43 public V dst() {
tom144de692014-08-29 11:38:44 -070044 return edges.isEmpty() ? null : edges.get(edges.size() - 1).dst();
tome3489412014-08-29 02:30:38 -070045 }
46
47 @Override
48 public double cost() {
49 return cost;
50 }
51
52 @Override
53 public List<E> edges() {
54 return ImmutableList.copyOf(edges);
55 }
56
57 @Override
58 public void setCost(double cost) {
59 this.cost = cost;
60 }
61
62 @Override
63 public Path<V, E> toImmutable() {
64 return new DefaultPath<>(edges, cost);
65 }
66
67 @Override
tom144de692014-08-29 11:38:44 -070068 public void insertEdge(E edge) {
69 checkNotNull(edge, "Edge cannot be null");
70 checkArgument(edges.isEmpty() || src().equals(edge.dst()),
71 "Edge destination must be the same as the current path source");
72 edges.add(0, edge);
73 }
74
75 @Override
tome3489412014-08-29 02:30:38 -070076 public void appendEdge(E edge) {
77 checkNotNull(edge, "Edge cannot be null");
tom144de692014-08-29 11:38:44 -070078 checkArgument(edges.isEmpty() || dst().equals(edge.src()),
tome3489412014-08-29 02:30:38 -070079 "Edge source must be the same as the current path destination");
tome3489412014-08-29 02:30:38 -070080 edges.add(edge);
81 }
82
83 @Override
tom144de692014-08-29 11:38:44 -070084 public void removeEdge(E edge) {
85 checkArgument(edge.src().equals(edge.dst()) ||
86 edges.indexOf(edge) == 0 ||
87 edges.lastIndexOf(edge) == edges.size() - 1,
88 "Edge must be at start or end of path, or it must be a cyclic edge");
89 edges.remove(edge);
tome3489412014-08-29 02:30:38 -070090 }
91
92 @Override
93 public String toString() {
94 return com.google.common.base.Objects.toStringHelper(this)
tom144de692014-08-29 11:38:44 -070095 .add("src", src())
96 .add("dst", dst())
tome3489412014-08-29 02:30:38 -070097 .add("cost", cost)
98 .add("edges", edges)
99 .toString();
100 }
101
102 @Override
103 public int hashCode() {
tom144de692014-08-29 11:38:44 -0700104 return Objects.hash(edges, cost);
tome3489412014-08-29 02:30:38 -0700105 }
106
107 @Override
108 public boolean equals(Object obj) {
109 if (obj instanceof DefaultMutablePath) {
110 final DefaultMutablePath other = (DefaultMutablePath) obj;
tom144de692014-08-29 11:38:44 -0700111 return Objects.equals(this.cost, other.cost) &&
tome3489412014-08-29 02:30:38 -0700112 Objects.equals(this.edges, other.edges);
113 }
114 return false;
115 }
tom144de692014-08-29 11:38:44 -0700116
tome3489412014-08-29 02:30:38 -0700117}