blob: b6c5e385ed28d6cf4ae8006f76cff38006d7f96b [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2014-present Open Networking Laboratory
Thomas Vachuska24c849c2014-10-27 09:53:05 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska24c849c2014-10-27 09:53:05 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska24c849c2014-10-27 09:53:05 -070015 */
tome3489412014-08-29 02:30:38 -070016package org.onlab.graph;
17
18import com.google.common.collect.ImmutableList;
19
20import java.util.ArrayList;
21import java.util.List;
22import java.util.Objects;
23
tomeadbb462014-09-07 16:10:19 -070024import static com.google.common.base.MoreObjects.toStringHelper;
tome3489412014-08-29 02:30:38 -070025import static com.google.common.base.Preconditions.checkArgument;
26import static com.google.common.base.Preconditions.checkNotNull;
27
28/**
29 * Simple concrete implementation of a directed graph path.
30 */
31public class DefaultMutablePath<V extends Vertex, E extends Edge<V>> implements MutablePath<V, E> {
32
tome3489412014-08-29 02:30:38 -070033 private final List<E> edges = new ArrayList<>();
34 private double cost = 0.0;
35
36 /**
37 * Creates a new empty path.
38 */
39 public DefaultMutablePath() {
40 }
41
42 /**
43 * Creates a new path as a copy of another path.
44 *
45 * @param path path to be copied
46 */
47 public DefaultMutablePath(Path<V, E> path) {
48 checkNotNull(path, "Path cannot be null");
tome3489412014-08-29 02:30:38 -070049 this.cost = path.cost();
50 edges.addAll(path.edges());
51 }
52
53 @Override
54 public V src() {
tom144de692014-08-29 11:38:44 -070055 return edges.isEmpty() ? null : edges.get(0).src();
tome3489412014-08-29 02:30:38 -070056 }
57
58 @Override
59 public V dst() {
tom144de692014-08-29 11:38:44 -070060 return edges.isEmpty() ? null : edges.get(edges.size() - 1).dst();
tome3489412014-08-29 02:30:38 -070061 }
62
63 @Override
64 public double cost() {
65 return cost;
66 }
67
68 @Override
69 public List<E> edges() {
70 return ImmutableList.copyOf(edges);
71 }
72
73 @Override
74 public void setCost(double cost) {
75 this.cost = cost;
76 }
77
78 @Override
79 public Path<V, E> toImmutable() {
80 return new DefaultPath<>(edges, cost);
81 }
82
83 @Override
tom144de692014-08-29 11:38:44 -070084 public void insertEdge(E edge) {
85 checkNotNull(edge, "Edge cannot be null");
86 checkArgument(edges.isEmpty() || src().equals(edge.dst()),
87 "Edge destination must be the same as the current path source");
88 edges.add(0, edge);
89 }
90
91 @Override
tome3489412014-08-29 02:30:38 -070092 public void appendEdge(E edge) {
93 checkNotNull(edge, "Edge cannot be null");
tom144de692014-08-29 11:38:44 -070094 checkArgument(edges.isEmpty() || dst().equals(edge.src()),
tome3489412014-08-29 02:30:38 -070095 "Edge source must be the same as the current path destination");
tome3489412014-08-29 02:30:38 -070096 edges.add(edge);
97 }
98
99 @Override
tom144de692014-08-29 11:38:44 -0700100 public void removeEdge(E edge) {
101 checkArgument(edge.src().equals(edge.dst()) ||
102 edges.indexOf(edge) == 0 ||
103 edges.lastIndexOf(edge) == edges.size() - 1,
104 "Edge must be at start or end of path, or it must be a cyclic edge");
105 edges.remove(edge);
tome3489412014-08-29 02:30:38 -0700106 }
107
108 @Override
109 public String toString() {
tomeadbb462014-09-07 16:10:19 -0700110 return toStringHelper(this)
tom144de692014-08-29 11:38:44 -0700111 .add("src", src())
112 .add("dst", dst())
tome3489412014-08-29 02:30:38 -0700113 .add("cost", cost)
114 .add("edges", edges)
115 .toString();
116 }
117
118 @Override
119 public int hashCode() {
tom144de692014-08-29 11:38:44 -0700120 return Objects.hash(edges, cost);
tome3489412014-08-29 02:30:38 -0700121 }
122
123 @Override
124 public boolean equals(Object obj) {
tomfc9a4ff2014-09-22 18:22:47 -0700125 if (this == obj) {
126 return true;
127 }
tome3489412014-08-29 02:30:38 -0700128 if (obj instanceof DefaultMutablePath) {
129 final DefaultMutablePath other = (DefaultMutablePath) obj;
tom144de692014-08-29 11:38:44 -0700130 return Objects.equals(this.cost, other.cost) &&
tome3489412014-08-29 02:30:38 -0700131 Objects.equals(this.edges, other.edges);
132 }
133 return false;
134 }
tom144de692014-08-29 11:38:44 -0700135
tome3489412014-08-29 02:30:38 -0700136}