Committed by
Gerrit Code Review
Introduce ResourcePath.Key
Change-Id: I4efd5c13a12f2bad5482f5b432e2f1ef2c337805
Showing
4 changed files
with
160 additions
and
79 deletions
1 | /* | 1 | /* |
2 | - * Copyright 2015 Open Networking Laboratory | 2 | + * Copyright 2015-2016 Open Networking Laboratory |
3 | * | 3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. | 5 | * you may not use this file except in compliance with the License. |
... | @@ -21,7 +21,6 @@ import com.google.common.collect.ImmutableList; | ... | @@ -21,7 +21,6 @@ import com.google.common.collect.ImmutableList; |
21 | import org.onosproject.net.DeviceId; | 21 | import org.onosproject.net.DeviceId; |
22 | import org.onosproject.net.PortNumber; | 22 | import org.onosproject.net.PortNumber; |
23 | 23 | ||
24 | -import java.util.LinkedList; | ||
25 | import java.util.List; | 24 | import java.util.List; |
26 | import java.util.Objects; | 25 | import java.util.Objects; |
27 | import java.util.Optional; | 26 | import java.util.Optional; |
... | @@ -50,12 +49,12 @@ import static com.google.common.base.Preconditions.checkState; | ... | @@ -50,12 +49,12 @@ import static com.google.common.base.Preconditions.checkState; |
50 | public abstract class ResourcePath { | 49 | public abstract class ResourcePath { |
51 | 50 | ||
52 | private final Discrete parent; | 51 | private final Discrete parent; |
53 | - private final Object last; | 52 | + private final Key key; |
54 | 53 | ||
55 | public static final Discrete ROOT = new Discrete(); | 54 | public static final Discrete ROOT = new Discrete(); |
56 | 55 | ||
57 | public static ResourcePath discrete(DeviceId device) { | 56 | public static ResourcePath discrete(DeviceId device) { |
58 | - return new Discrete(ImmutableList.of(device)); | 57 | + return new Discrete(Key.of(device)); |
59 | } | 58 | } |
60 | 59 | ||
61 | /** | 60 | /** |
... | @@ -66,10 +65,7 @@ public abstract class ResourcePath { | ... | @@ -66,10 +65,7 @@ public abstract class ResourcePath { |
66 | * @return resource path instance | 65 | * @return resource path instance |
67 | */ | 66 | */ |
68 | public static ResourcePath discrete(DeviceId device, Object... components) { | 67 | public static ResourcePath discrete(DeviceId device, Object... components) { |
69 | - return new Discrete(ImmutableList.builder() | 68 | + return new Discrete(Key.of(device, components)); |
70 | - .add(device) | ||
71 | - .add(components) | ||
72 | - .build()); | ||
73 | } | 69 | } |
74 | 70 | ||
75 | /** | 71 | /** |
... | @@ -81,11 +77,7 @@ public abstract class ResourcePath { | ... | @@ -81,11 +77,7 @@ public abstract class ResourcePath { |
81 | * @return resource path instance | 77 | * @return resource path instance |
82 | */ | 78 | */ |
83 | public static ResourcePath discrete(DeviceId device, PortNumber port, Object... components) { | 79 | public static ResourcePath discrete(DeviceId device, PortNumber port, Object... components) { |
84 | - return new Discrete(ImmutableList.builder() | 80 | + return new Discrete(Key.of(device, port, components)); |
85 | - .add(device) | ||
86 | - .add(port) | ||
87 | - .add(components) | ||
88 | - .build()); | ||
89 | } | 81 | } |
90 | 82 | ||
91 | /** | 83 | /** |
... | @@ -100,10 +92,7 @@ public abstract class ResourcePath { | ... | @@ -100,10 +92,7 @@ public abstract class ResourcePath { |
100 | checkArgument(components.length > 0, | 92 | checkArgument(components.length > 0, |
101 | "Length of components must be greater thant 0, but " + components.length); | 93 | "Length of components must be greater thant 0, but " + components.length); |
102 | 94 | ||
103 | - return new Continuous(ImmutableList.builder() | 95 | + return new Continuous(Key.of(device, components), value); |
104 | - .add(device) | ||
105 | - .add(components) | ||
106 | - .build(), value); | ||
107 | } | 96 | } |
108 | 97 | ||
109 | /** | 98 | /** |
... | @@ -116,49 +105,29 @@ public abstract class ResourcePath { | ... | @@ -116,49 +105,29 @@ public abstract class ResourcePath { |
116 | * @return resource path instance | 105 | * @return resource path instance |
117 | */ | 106 | */ |
118 | public static ResourcePath continuous(double value, DeviceId device, PortNumber port, Object... components) { | 107 | public static ResourcePath continuous(double value, DeviceId device, PortNumber port, Object... components) { |
119 | - return new Continuous(ImmutableList.builder() | 108 | + return new Continuous(Key.of(device, port, components), value); |
120 | - .add(device) | ||
121 | - .add(port) | ||
122 | - .add(components) | ||
123 | - .build(), value); | ||
124 | } | 109 | } |
125 | 110 | ||
126 | /** | 111 | /** |
127 | - * Creates an resource path from the specified components. | 112 | + * Creates an resource path from the specified key. |
128 | * | 113 | * |
129 | - * @param components components of the path. The order represents hierarchical structure of the resource. | 114 | + * @param key key of the path |
130 | */ | 115 | */ |
131 | - protected ResourcePath(List<Object> components) { | 116 | + protected ResourcePath(Key key) { |
132 | - checkNotNull(components); | 117 | + checkNotNull(key); |
133 | - checkArgument(!components.isEmpty()); | ||
134 | 118 | ||
135 | - LinkedList<Object> children = new LinkedList<>(components); | 119 | + this.key = key; |
136 | - this.last = children.pollLast(); | 120 | + if (key.components.size() == 1) { |
137 | - if (children.isEmpty()) { | ||
138 | this.parent = ROOT; | 121 | this.parent = ROOT; |
139 | } else { | 122 | } else { |
140 | - this.parent = new Discrete(children); | 123 | + this.parent = new Discrete(key.parent()); |
141 | } | 124 | } |
142 | } | 125 | } |
143 | 126 | ||
144 | - /** | ||
145 | - * Creates an resource path from the specified parent and child. | ||
146 | - * | ||
147 | - * @param parent the parent of this resource | ||
148 | - * @param last a child of the parent | ||
149 | - */ | ||
150 | - protected ResourcePath(Discrete parent, Object last) { | ||
151 | - checkNotNull(parent); | ||
152 | - checkNotNull(last); | ||
153 | - | ||
154 | - this.parent = parent; | ||
155 | - this.last = last; | ||
156 | - } | ||
157 | - | ||
158 | // for serialization | 127 | // for serialization |
159 | private ResourcePath() { | 128 | private ResourcePath() { |
160 | this.parent = null; | 129 | this.parent = null; |
161 | - this.last = null; | 130 | + this.key = Key.ROOT; |
162 | } | 131 | } |
163 | 132 | ||
164 | /** | 133 | /** |
... | @@ -167,15 +136,7 @@ public abstract class ResourcePath { | ... | @@ -167,15 +136,7 @@ public abstract class ResourcePath { |
167 | * @return the components of this resource path | 136 | * @return the components of this resource path |
168 | */ | 137 | */ |
169 | public List<Object> components() { | 138 | public List<Object> components() { |
170 | - LinkedList<Object> components = new LinkedList<>(); | 139 | + return key.components; |
171 | - | ||
172 | - ResourcePath current = this; | ||
173 | - while (current.parent().isPresent()) { | ||
174 | - components.addFirst(current.last); | ||
175 | - current = current.parent; | ||
176 | - } | ||
177 | - | ||
178 | - return components; | ||
179 | } | 140 | } |
180 | 141 | ||
181 | /** | 142 | /** |
... | @@ -199,7 +160,7 @@ public abstract class ResourcePath { | ... | @@ -199,7 +160,7 @@ public abstract class ResourcePath { |
199 | public ResourcePath child(Object child) { | 160 | public ResourcePath child(Object child) { |
200 | checkState(this instanceof Discrete); | 161 | checkState(this instanceof Discrete); |
201 | 162 | ||
202 | - return new Discrete((Discrete) this, child); | 163 | + return new Discrete(key().child(child)); |
203 | } | 164 | } |
204 | 165 | ||
205 | /** | 166 | /** |
... | @@ -213,7 +174,7 @@ public abstract class ResourcePath { | ... | @@ -213,7 +174,7 @@ public abstract class ResourcePath { |
213 | public ResourcePath child(Object child, double value) { | 174 | public ResourcePath child(Object child, double value) { |
214 | checkState(this instanceof Discrete); | 175 | checkState(this instanceof Discrete); |
215 | 176 | ||
216 | - return new Continuous((Discrete) this, child, value); | 177 | + return new Continuous(key.child(child), value); |
217 | } | 178 | } |
218 | 179 | ||
219 | /** | 180 | /** |
... | @@ -223,12 +184,24 @@ public abstract class ResourcePath { | ... | @@ -223,12 +184,24 @@ public abstract class ResourcePath { |
223 | * The return value is equal to the last object of {@code components()}. | 184 | * The return value is equal to the last object of {@code components()}. |
224 | */ | 185 | */ |
225 | public Object last() { | 186 | public Object last() { |
226 | - return last; | 187 | + if (key.components.isEmpty()) { |
188 | + return null; | ||
189 | + } | ||
190 | + return key.components.get(key.components.size() - 1); | ||
191 | + } | ||
192 | + | ||
193 | + /** | ||
194 | + * Returns the key of this resource path. | ||
195 | + * | ||
196 | + * @return the key of this resource path | ||
197 | + */ | ||
198 | + public Key key() { | ||
199 | + return key; | ||
227 | } | 200 | } |
228 | 201 | ||
229 | @Override | 202 | @Override |
230 | public int hashCode() { | 203 | public int hashCode() { |
231 | - return Objects.hash(this.parent, this.last); | 204 | + return key.hashCode(); |
232 | } | 205 | } |
233 | 206 | ||
234 | @Override | 207 | @Override |
... | @@ -240,15 +213,13 @@ public abstract class ResourcePath { | ... | @@ -240,15 +213,13 @@ public abstract class ResourcePath { |
240 | return false; | 213 | return false; |
241 | } | 214 | } |
242 | final ResourcePath that = (ResourcePath) obj; | 215 | final ResourcePath that = (ResourcePath) obj; |
243 | - return Objects.equals(this.parent, that.parent) | 216 | + return Objects.equals(this.key, that.key); |
244 | - && Objects.equals(this.last, that.last); | ||
245 | } | 217 | } |
246 | 218 | ||
247 | @Override | 219 | @Override |
248 | public String toString() { | 220 | public String toString() { |
249 | return MoreObjects.toStringHelper(this) | 221 | return MoreObjects.toStringHelper(this) |
250 | - .add("parent", parent) | 222 | + .add("key", key) |
251 | - .add("last", last) | ||
252 | .toString(); | 223 | .toString(); |
253 | } | 224 | } |
254 | 225 | ||
... | @@ -266,12 +237,8 @@ public abstract class ResourcePath { | ... | @@ -266,12 +237,8 @@ public abstract class ResourcePath { |
266 | super(); | 237 | super(); |
267 | } | 238 | } |
268 | 239 | ||
269 | - private Discrete(List<Object> components) { | 240 | + private Discrete(Key key) { |
270 | - super(components); | 241 | + super(key); |
271 | - } | ||
272 | - | ||
273 | - private Discrete(Discrete parent, Object last) { | ||
274 | - super(parent, last); | ||
275 | } | 242 | } |
276 | } | 243 | } |
277 | 244 | ||
... | @@ -284,17 +251,34 @@ public abstract class ResourcePath { | ... | @@ -284,17 +251,34 @@ public abstract class ResourcePath { |
284 | */ | 251 | */ |
285 | @Beta | 252 | @Beta |
286 | public static final class Continuous extends ResourcePath { | 253 | public static final class Continuous extends ResourcePath { |
287 | - // Note: value is not taken into account for equality | ||
288 | private final double value; | 254 | private final double value; |
289 | 255 | ||
290 | - private Continuous(List<Object> components, double value) { | 256 | + private Continuous(Key key, double value) { |
291 | - super(components); | 257 | + super(key); |
292 | this.value = value; | 258 | this.value = value; |
293 | } | 259 | } |
294 | 260 | ||
295 | - public Continuous(Discrete parent, Object last, double value) { | 261 | + @Override |
296 | - super(parent, last); | 262 | + public int hashCode() { |
297 | - this.value = value; | 263 | + return Objects.hash(this.key(), this.value); |
264 | + } | ||
265 | + | ||
266 | + @Override | ||
267 | + public boolean equals(Object obj) { | ||
268 | + if (this == obj) { | ||
269 | + return true; | ||
270 | + } | ||
271 | + | ||
272 | + if (!(obj instanceof Continuous)) { | ||
273 | + return false; | ||
274 | + } | ||
275 | + | ||
276 | + if (!super.equals(obj)) { | ||
277 | + return false; | ||
278 | + } | ||
279 | + | ||
280 | + final Continuous other = (Continuous) obj; | ||
281 | + return Objects.equals(this.key(), other.key()); | ||
298 | } | 282 | } |
299 | 283 | ||
300 | /** | 284 | /** |
... | @@ -306,4 +290,80 @@ public abstract class ResourcePath { | ... | @@ -306,4 +290,80 @@ public abstract class ResourcePath { |
306 | return value; | 290 | return value; |
307 | } | 291 | } |
308 | } | 292 | } |
293 | + | ||
294 | + /** | ||
295 | + * Represents key of resource path used as a key in ResourceStore. | ||
296 | + * This class is exposed to public, but intended to use only in ResourceStore implementations. | ||
297 | + */ | ||
298 | + @Beta | ||
299 | + public static final class Key { | ||
300 | + private static final Key ROOT = new Key(); | ||
301 | + | ||
302 | + private final ImmutableList<Object> components; | ||
303 | + | ||
304 | + private static Key of(DeviceId device, Object... components) { | ||
305 | + return new Key(ImmutableList.builder() | ||
306 | + .add(device) | ||
307 | + .add(components) | ||
308 | + .build()); | ||
309 | + } | ||
310 | + | ||
311 | + private static Key of(DeviceId device, PortNumber port, Object... components) { | ||
312 | + return new Key(ImmutableList.builder() | ||
313 | + .add(device) | ||
314 | + .add(port) | ||
315 | + .add(components) | ||
316 | + .build()); | ||
317 | + } | ||
318 | + | ||
319 | + private Key(ImmutableList<Object> components) { | ||
320 | + this.components = checkNotNull(components); | ||
321 | + } | ||
322 | + | ||
323 | + // for serializer | ||
324 | + private Key() { | ||
325 | + this.components = ImmutableList.of(); | ||
326 | + } | ||
327 | + | ||
328 | + // IndexOutOfBoundsException is raised when the instance is equal to ROOT | ||
329 | + private Key parent() { | ||
330 | + if (components.size() == 1) { | ||
331 | + return ROOT; | ||
332 | + } else { | ||
333 | + return new Key(components.subList(0, components.size() - 1)); | ||
334 | + } | ||
335 | + } | ||
336 | + | ||
337 | + private Key child(Object child) { | ||
338 | + return new Key(ImmutableList.builder() | ||
339 | + .add(components) | ||
340 | + .add(child) | ||
341 | + .build()); | ||
342 | + } | ||
343 | + | ||
344 | + @Override | ||
345 | + public int hashCode() { | ||
346 | + return components.hashCode(); | ||
347 | + } | ||
348 | + | ||
349 | + @Override | ||
350 | + public boolean equals(Object obj) { | ||
351 | + if (this == obj) { | ||
352 | + return true; | ||
353 | + } | ||
354 | + if (!(obj instanceof Key)) { | ||
355 | + return false; | ||
356 | + } | ||
357 | + | ||
358 | + Key other = (Key) obj; | ||
359 | + return Objects.equals(this.components, other.components); | ||
360 | + } | ||
361 | + | ||
362 | + @Override | ||
363 | + public String toString() { | ||
364 | + return MoreObjects.toStringHelper(this) | ||
365 | + .add("components", components) | ||
366 | + .toString(); | ||
367 | + } | ||
368 | + } | ||
309 | } | 369 | } | ... | ... |
... | @@ -43,12 +43,12 @@ public class ResourcePathTest { | ... | @@ -43,12 +43,12 @@ public class ResourcePathTest { |
43 | ResourcePath sameAsResource1 = ResourcePath.discrete(D1, P1, VLAN1); | 43 | ResourcePath sameAsResource1 = ResourcePath.discrete(D1, P1, VLAN1); |
44 | ResourcePath resource2 = ResourcePath.discrete(D2, P1, VLAN1); | 44 | ResourcePath resource2 = ResourcePath.discrete(D2, P1, VLAN1); |
45 | ResourcePath resource3 = ResourcePath.continuous(BW1.bps(), D1, P1, BW1); | 45 | ResourcePath resource3 = ResourcePath.continuous(BW1.bps(), D1, P1, BW1); |
46 | - ResourcePath sameAsResource3 = ResourcePath.continuous(BW2.bps(), D1, P1, BW1); | 46 | + ResourcePath sameAsResource3 = ResourcePath.continuous(BW1.bps(), D1, P1, BW1); |
47 | 47 | ||
48 | new EqualsTester() | 48 | new EqualsTester() |
49 | .addEqualityGroup(resource1, sameAsResource1) | 49 | .addEqualityGroup(resource1, sameAsResource1) |
50 | .addEqualityGroup(resource2) | 50 | .addEqualityGroup(resource2) |
51 | - .addEqualityGroup(resource3, sameAsResource3) // this is intentional | 51 | + .addEqualityGroup(resource3, sameAsResource3) |
52 | .testEquals(); | 52 | .testEquals(); |
53 | } | 53 | } |
54 | 54 | ||
... | @@ -60,6 +60,21 @@ public class ResourcePathTest { | ... | @@ -60,6 +60,21 @@ public class ResourcePathTest { |
60 | } | 60 | } |
61 | 61 | ||
62 | @Test | 62 | @Test |
63 | + public void testKeyEquality() { | ||
64 | + ResourcePath.Key key1 = ResourcePath.discrete(D1, P1, VLAN1).key(); | ||
65 | + ResourcePath.Key sameAsKey1 = ResourcePath.discrete(D1, P1, VLAN1).key(); | ||
66 | + ResourcePath.Key key2 = ResourcePath.discrete(D2, P1, VLAN1).key(); | ||
67 | + ResourcePath.Key key3 = ResourcePath.continuous(BW1.bps(), D1, P1, BW1).key(); | ||
68 | + // intentionally set a different value | ||
69 | + ResourcePath.Key sameAsKey3 = ResourcePath.continuous(BW2.bps(), D1, P1, BW1).key(); | ||
70 | + | ||
71 | + new EqualsTester() | ||
72 | + .addEqualityGroup(key1, sameAsKey1) | ||
73 | + .addEqualityGroup(key2) | ||
74 | + .addEqualityGroup(key3, sameAsKey3); | ||
75 | + } | ||
76 | + | ||
77 | + @Test | ||
63 | public void testThereIsParent() { | 78 | public void testThereIsParent() { |
64 | ResourcePath path = ResourcePath.discrete(D1, P1, VLAN1); | 79 | ResourcePath path = ResourcePath.discrete(D1, P1, VLAN1); |
65 | ResourcePath parent = ResourcePath.discrete(D1, P1); | 80 | ResourcePath parent = ResourcePath.discrete(D1, P1); | ... | ... |
1 | /* | 1 | /* |
2 | - * Copyright 2014-2015 Open Networking Laboratory | 2 | + * Copyright 2014-2016 Open Networking Laboratory |
3 | * | 3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. | 5 | * you may not use this file except in compliance with the License. |
... | @@ -430,6 +430,7 @@ public final class KryoNamespaces { | ... | @@ -430,6 +430,7 @@ public final class KryoNamespaces { |
430 | ResourcePath.class, | 430 | ResourcePath.class, |
431 | ResourcePath.Discrete.class, | 431 | ResourcePath.Discrete.class, |
432 | ResourcePath.Continuous.class, | 432 | ResourcePath.Continuous.class, |
433 | + ResourcePath.Key.class, | ||
433 | ResourceAllocation.class, | 434 | ResourceAllocation.class, |
434 | // Constraints | 435 | // Constraints |
435 | LambdaConstraint.class, | 436 | LambdaConstraint.class, | ... | ... |
1 | /* | 1 | /* |
2 | - * Copyright 2014-2015 Open Networking Laboratory | 2 | + * Copyright 2014-2016 Open Networking Laboratory |
3 | * | 3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. | 5 | * you may not use this file except in compliance with the License. |
... | @@ -378,6 +378,11 @@ public class KryoSerializerTest { | ... | @@ -378,6 +378,11 @@ public class KryoSerializerTest { |
378 | } | 378 | } |
379 | 379 | ||
380 | @Test | 380 | @Test |
381 | + public void testResourceKey() { | ||
382 | + testSerializedEquals(ResourcePath.discrete(DID1, P1).key()); | ||
383 | + } | ||
384 | + | ||
385 | + @Test | ||
381 | public void testResourceAllocation() { | 386 | public void testResourceAllocation() { |
382 | testSerializedEquals(new org.onosproject.net.newresource.ResourceAllocation( | 387 | testSerializedEquals(new org.onosproject.net.newresource.ResourceAllocation( |
383 | ResourcePath.discrete(DID1, P1, VLAN1), | 388 | ResourcePath.discrete(DID1, P1, VLAN1), | ... | ... |
-
Please register or login to post a comment