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