blob: 1e8d3d61405990878085e9a9e7cc887bb10a1d99 [file] [log] [blame]
Nikhil Cheerlaf7c2e1a2015-07-09 12:06:37 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Nikhil Cheerlaf7c2e1a2015-07-09 12:06:37 -07003 *
4 * 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
7 *
8 * 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.
15 */
16
17
18package org.onlab.graph;
19
20import java.util.List;
21import java.util.Objects;
Nikhil Cheerlaf7c2e1a2015-07-09 12:06:37 -070022
Nikhil Cheerlaf7c2e1a2015-07-09 12:06:37 -070023import static com.google.common.base.MoreObjects.toStringHelper;
24
Thomas Vachuska48e64e42015-09-22 15:32:55 -070025/**
26 * Pair of disjoint paths.
27 *
28 * @param <V> type of vertex
29 * @param <E> type of edge
30 */
Nikhil Cheerlaf7c2e1a2015-07-09 12:06:37 -070031public class DisjointPathPair<V extends Vertex, E extends Edge<V>> implements Path<V, E> {
Thomas Vachuska48e64e42015-09-22 15:32:55 -070032
HIGUCHI Yutaca9cc8e2015-10-29 23:26:51 -070033 private final Path<V, E> primary, secondary;
34 private boolean primaryActive = true;
Nikhil Cheerlaf7c2e1a2015-07-09 12:06:37 -070035
36 /**
Thomas Vachuska48e64e42015-09-22 15:32:55 -070037 * Creates a disjoint path pair from two paths.
Nikhil Cheerlaf7c2e1a2015-07-09 12:06:37 -070038 *
Thomas Vachuska48e64e42015-09-22 15:32:55 -070039 * @param primary primary path
40 * @param secondary secondary path
Nikhil Cheerlaf7c2e1a2015-07-09 12:06:37 -070041 */
Thomas Vachuska48e64e42015-09-22 15:32:55 -070042 public DisjointPathPair(Path<V, E> primary, Path<V, E> secondary) {
43 this.primary = primary;
44 this.secondary = secondary;
Nikhil Cheerlaf7c2e1a2015-07-09 12:06:37 -070045 }
46
47 @Override
48 public V src() {
Thomas Vachuska48e64e42015-09-22 15:32:55 -070049 return primary.src();
Nikhil Cheerlaf7c2e1a2015-07-09 12:06:37 -070050 }
51
52 @Override
53 public V dst() {
Thomas Vachuska48e64e42015-09-22 15:32:55 -070054 return primary.dst();
55 }
56
57 /**
58 * Returns the primary path.
59 *
60 * @return primary path
61 */
62 public Path<V, E> primary() {
63 return primary;
64 }
65
66 /**
67 * Returns the secondary path.
68 *
Yuta HIGUCHIc3d69f52016-08-08 11:52:52 -070069 * @return secondary path, or null if there is no secondary path available.
Thomas Vachuska48e64e42015-09-22 15:32:55 -070070 */
71 public Path<V, E> secondary() {
72 return secondary;
Nikhil Cheerlaf7c2e1a2015-07-09 12:06:37 -070073 }
74
75 @Override
76 public double cost() {
Thomas Vachuska48e64e42015-09-22 15:32:55 -070077 return hasBackup() ? primary.cost() + secondary.cost() : primary.cost();
Nikhil Cheerlaf7c2e1a2015-07-09 12:06:37 -070078 }
79
80 @Override
81 public List<E> edges() {
Thomas Vachuska48e64e42015-09-22 15:32:55 -070082 return primaryActive || !hasBackup() ? primary.edges() : secondary.edges();
Nikhil Cheerlaf7c2e1a2015-07-09 12:06:37 -070083 }
84
85 /**
86 * Checks if this path pair contains a backup/secondary path.
87 *
88 * @return boolean representing whether it has backup
89 */
90 public boolean hasBackup() {
HIGUCHI Yutaca9cc8e2015-10-29 23:26:51 -070091 return secondary != null;
Nikhil Cheerlaf7c2e1a2015-07-09 12:06:37 -070092 }
93
94 @Override
95 public String toString() {
96 return toStringHelper(this)
97 .add("src", src())
98 .add("dst", dst())
99 .add("cost", cost())
100 .add("edges", edges())
101 .toString();
102 }
103
104 @Override
105 public int hashCode() {
HIGUCHI Yutaca9cc8e2015-10-29 23:26:51 -0700106 // Note: DisjointPathPair with primary and secondary swapped
107 // must result in same hashCode
108 return hasBackup() ? primary.hashCode() + secondary.hashCode() :
Thomas Vachuska48e64e42015-09-22 15:32:55 -0700109 Objects.hash(primary);
Nikhil Cheerlaf7c2e1a2015-07-09 12:06:37 -0700110 }
111
112 @Override
113 public boolean equals(Object obj) {
114 if (this == obj) {
115 return true;
116 }
117 if (obj instanceof DisjointPathPair) {
118 final DisjointPathPair other = (DisjointPathPair) obj;
119 return Objects.equals(this.src(), other.src()) &&
120 Objects.equals(this.dst(), other.dst()) &&
Thomas Vachuska48e64e42015-09-22 15:32:55 -0700121 (Objects.equals(this.primary, other.primary) &&
122 Objects.equals(this.secondary, other.secondary)) ||
123 (Objects.equals(this.primary, other.secondary) &&
124 Objects.equals(this.secondary, other.primary));
Nikhil Cheerlaf7c2e1a2015-07-09 12:06:37 -0700125 }
126 return false;
127 }
128
129 /**
130 * Returns number of paths inside this path pair object.
131 *
132 * @return number of paths
133 */
134 public int size() {
Thomas Vachuska48e64e42015-09-22 15:32:55 -0700135 return hasBackup() ? 2 : 1;
Nikhil Cheerlaf7c2e1a2015-07-09 12:06:37 -0700136 }
137}