Sho SHIMIZU
Committed by Gerrit Code Review

Define a class representing a set of discrete resources

Change-Id: Iaafc5ca68ae3b1330e6c8b0b2476d835a42731b6
...@@ -30,7 +30,6 @@ import org.onosproject.store.service.StorageService; ...@@ -30,7 +30,6 @@ import org.onosproject.store.service.StorageService;
30 import org.onosproject.store.service.TransactionContext; 30 import org.onosproject.store.service.TransactionContext;
31 import org.onosproject.store.service.Versioned; 31 import org.onosproject.store.service.Versioned;
32 32
33 -import java.util.LinkedHashSet;
34 import java.util.List; 33 import java.util.List;
35 import java.util.Map; 34 import java.util.Map;
36 import java.util.Set; 35 import java.util.Set;
...@@ -42,19 +41,19 @@ import static org.onosproject.store.resource.impl.ConsistentResourceStore.SERIAL ...@@ -42,19 +41,19 @@ import static org.onosproject.store.resource.impl.ConsistentResourceStore.SERIAL
42 41
43 class ConsistentDiscreteResourceSubStore { 42 class ConsistentDiscreteResourceSubStore {
44 private ConsistentMap<DiscreteResourceId, ResourceConsumerId> consumers; 43 private ConsistentMap<DiscreteResourceId, ResourceConsumerId> consumers;
45 - private ConsistentMap<DiscreteResourceId, Set<DiscreteResource>> childMap; 44 + private ConsistentMap<DiscreteResourceId, DiscreteResources> childMap;
46 45
47 ConsistentDiscreteResourceSubStore(StorageService service) { 46 ConsistentDiscreteResourceSubStore(StorageService service) {
48 this.consumers = service.<DiscreteResourceId, ResourceConsumerId>consistentMapBuilder() 47 this.consumers = service.<DiscreteResourceId, ResourceConsumerId>consistentMapBuilder()
49 .withName(MapNames.DISCRETE_CONSUMER_MAP) 48 .withName(MapNames.DISCRETE_CONSUMER_MAP)
50 .withSerializer(SERIALIZER) 49 .withSerializer(SERIALIZER)
51 .build(); 50 .build();
52 - this.childMap = service.<DiscreteResourceId, Set<DiscreteResource>>consistentMapBuilder() 51 + this.childMap = service.<DiscreteResourceId, DiscreteResources>consistentMapBuilder()
53 .withName(MapNames.DISCRETE_CHILD_MAP) 52 .withName(MapNames.DISCRETE_CHILD_MAP)
54 .withSerializer(SERIALIZER) 53 .withSerializer(SERIALIZER)
55 .build(); 54 .build();
56 55
57 - Tools.retryable(() -> childMap.put(Resource.ROOT.id(), new LinkedHashSet<>()), 56 + Tools.retryable(() -> childMap.put(Resource.ROOT.id(), DiscreteResources.empty()),
58 ConsistentMapException.class, MAX_RETRIES, RETRY_DELAY); 57 ConsistentMapException.class, MAX_RETRIES, RETRY_DELAY);
59 } 58 }
60 59
...@@ -73,13 +72,13 @@ class ConsistentDiscreteResourceSubStore { ...@@ -73,13 +72,13 @@ class ConsistentDiscreteResourceSubStore {
73 } 72 }
74 73
75 Set<DiscreteResource> getChildResources(DiscreteResourceId parent) { 74 Set<DiscreteResource> getChildResources(DiscreteResourceId parent) {
76 - Versioned<Set<DiscreteResource>> children = childMap.get(parent); 75 + Versioned<DiscreteResources> children = childMap.get(parent);
77 76
78 if (children == null) { 77 if (children == null) {
79 return ImmutableSet.of(); 78 return ImmutableSet.of();
80 } 79 }
81 80
82 - return children.value(); 81 + return children.value().values();
83 } 82 }
84 83
85 boolean isAvailable(DiscreteResource resource) { 84 boolean isAvailable(DiscreteResource resource) {
......
...@@ -71,6 +71,7 @@ public class ConsistentResourceStore extends AbstractStore<ResourceEvent, Resour ...@@ -71,6 +71,7 @@ public class ConsistentResourceStore extends AbstractStore<ResourceEvent, Resour
71 71
72 static final Serializer SERIALIZER = Serializer.using( 72 static final Serializer SERIALIZER = Serializer.using(
73 Arrays.asList(KryoNamespaces.API), 73 Arrays.asList(KryoNamespaces.API),
74 + DiscreteResources.class,
74 ContinuousResourceAllocation.class); 75 ContinuousResourceAllocation.class);
75 76
76 // TODO: We should provide centralized values for this 77 // TODO: We should provide centralized values for this
......
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
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 +package org.onosproject.store.resource.impl;
17 +
18 +import com.google.common.base.MoreObjects;
19 +import com.google.common.collect.Sets;
20 +import org.onosproject.net.resource.DiscreteResource;
21 +import org.onosproject.net.resource.DiscreteResourceId;
22 +import org.onosproject.net.resource.Resources;
23 +
24 +import java.util.LinkedHashSet;
25 +import java.util.List;
26 +import java.util.Objects;
27 +import java.util.Optional;
28 +import java.util.Set;
29 +
30 +final class DiscreteResources {
31 + private final Set<DiscreteResource> values;
32 +
33 + static DiscreteResources empty() {
34 + return new DiscreteResources();
35 + }
36 +
37 + private DiscreteResources() {
38 + this.values = new LinkedHashSet<>();
39 + }
40 +
41 + DiscreteResources(List<DiscreteResource> values) {
42 + this.values = new LinkedHashSet<>(values);
43 + }
44 +
45 + private DiscreteResources(Set<DiscreteResource> values) {
46 + this.values = values;
47 + }
48 +
49 + Optional<DiscreteResource> lookup(DiscreteResourceId id) {
50 + DiscreteResource resource = Resources.discrete(id).resource();
51 + if (values.contains(resource)) {
52 + return Optional.of(resource);
53 + } else {
54 + return Optional.empty();
55 + }
56 + }
57 +
58 + DiscreteResources difference(DiscreteResources other) {
59 + return new DiscreteResources(Sets.difference(this.values, other.values));
60 + }
61 +
62 + boolean isEmpty() {
63 + return values.isEmpty();
64 + }
65 +
66 + boolean containsAny(List<DiscreteResource> other) {
67 + return other.stream().anyMatch(values::contains);
68 + }
69 +
70 + // returns a new instance, not mutate the current instance
71 + DiscreteResources add(DiscreteResources other) {
72 + Set<DiscreteResource> newValues = new LinkedHashSet<>(this.values);
73 + newValues.addAll(other.values);
74 + return new DiscreteResources(newValues);
75 + }
76 +
77 + // returns a new instance, not mutate the current instance
78 + DiscreteResources remove(List<DiscreteResource> removed) {
79 + Set<DiscreteResource> newValues = new LinkedHashSet<>(this.values);
80 + newValues.removeAll(removed);
81 + return new DiscreteResources(newValues);
82 + }
83 +
84 + Set<DiscreteResource> values() {
85 + // breaks immutability, but intentionally returns the field
86 + // because this class is transient
87 + return values;
88 + }
89 +
90 + @Override
91 + public int hashCode() {
92 + return Objects.hash(values);
93 + }
94 +
95 + @Override
96 + public boolean equals(Object obj) {
97 + if (this == obj) {
98 + return true;
99 + }
100 + if (obj == null || getClass() != obj.getClass()) {
101 + return false;
102 + }
103 + final DiscreteResources other = (DiscreteResources) obj;
104 + return Objects.equals(this.values, other.values);
105 + }
106 +
107 + @Override
108 + public String toString() {
109 + return MoreObjects.toStringHelper(this)
110 + .add("values", values)
111 + .toString();
112 + }
113 +}
...@@ -15,27 +15,23 @@ ...@@ -15,27 +15,23 @@
15 */ 15 */
16 package org.onosproject.store.resource.impl; 16 package org.onosproject.store.resource.impl;
17 17
18 -import com.google.common.collect.Sets;
19 import org.onosproject.net.resource.DiscreteResource; 18 import org.onosproject.net.resource.DiscreteResource;
20 import org.onosproject.net.resource.DiscreteResourceId; 19 import org.onosproject.net.resource.DiscreteResourceId;
21 import org.onosproject.net.resource.Resource; 20 import org.onosproject.net.resource.Resource;
22 import org.onosproject.net.resource.ResourceConsumerId; 21 import org.onosproject.net.resource.ResourceConsumerId;
23 -import org.onosproject.net.resource.Resources;
24 import org.onosproject.store.service.TransactionContext; 22 import org.onosproject.store.service.TransactionContext;
25 import org.onosproject.store.service.TransactionalMap; 23 import org.onosproject.store.service.TransactionalMap;
26 import org.slf4j.Logger; 24 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory; 25 import org.slf4j.LoggerFactory;
28 26
29 -import java.util.LinkedHashSet;
30 import java.util.List; 27 import java.util.List;
31 import java.util.Optional; 28 import java.util.Optional;
32 -import java.util.Set;
33 29
34 import static org.onosproject.store.resource.impl.ConsistentResourceStore.SERIALIZER; 30 import static org.onosproject.store.resource.impl.ConsistentResourceStore.SERIALIZER;
35 31
36 class TransactionalDiscreteResourceSubStore { 32 class TransactionalDiscreteResourceSubStore {
37 private final Logger log = LoggerFactory.getLogger(getClass()); 33 private final Logger log = LoggerFactory.getLogger(getClass());
38 - private final TransactionalMap<DiscreteResourceId, Set<DiscreteResource>> childMap; 34 + private final TransactionalMap<DiscreteResourceId, DiscreteResources> childMap;
39 private final TransactionalMap<DiscreteResourceId, ResourceConsumerId> consumers; 35 private final TransactionalMap<DiscreteResourceId, ResourceConsumerId> consumers;
40 36
41 TransactionalDiscreteResourceSubStore(TransactionContext tx) { 37 TransactionalDiscreteResourceSubStore(TransactionContext tx) {
...@@ -49,17 +45,12 @@ class TransactionalDiscreteResourceSubStore { ...@@ -49,17 +45,12 @@ class TransactionalDiscreteResourceSubStore {
49 return Optional.of(Resource.ROOT); 45 return Optional.of(Resource.ROOT);
50 } 46 }
51 47
52 - Set<DiscreteResource> values = childMap.get(id.parent().get()); 48 + DiscreteResources values = childMap.get(id.parent().get());
53 if (values == null) { 49 if (values == null) {
54 return Optional.empty(); 50 return Optional.empty();
55 } 51 }
56 52
57 - DiscreteResource resource = Resources.discrete(id).resource(); 53 + return values.lookup(id);
58 - if (values.contains(resource)) {
59 - return Optional.of(resource);
60 - } else {
61 - return Optional.empty();
62 - }
63 } 54 }
64 55
65 boolean register(DiscreteResourceId key, List<DiscreteResource> values) { 56 boolean register(DiscreteResourceId key, List<DiscreteResource> values) {
...@@ -68,21 +59,20 @@ class TransactionalDiscreteResourceSubStore { ...@@ -68,21 +59,20 @@ class TransactionalDiscreteResourceSubStore {
68 return true; 59 return true;
69 } 60 }
70 61
71 - Set<DiscreteResource> requested = new LinkedHashSet<>(values); 62 + DiscreteResources requested = new DiscreteResources(values);
72 - Set<DiscreteResource> oldValues = childMap.putIfAbsent(key, requested); 63 + DiscreteResources oldValues = childMap.putIfAbsent(key, requested);
73 if (oldValues == null) { 64 if (oldValues == null) {
74 return true; 65 return true;
75 } 66 }
76 67
77 - Set<DiscreteResource> addedValues = Sets.difference(requested, oldValues); 68 + DiscreteResources addedValues = requested.difference(oldValues);
78 // no new value, then no-op 69 // no new value, then no-op
79 if (addedValues.isEmpty()) { 70 if (addedValues.isEmpty()) {
80 // don't write to map because all values are already stored 71 // don't write to map because all values are already stored
81 return true; 72 return true;
82 } 73 }
83 74
84 - Set<DiscreteResource> newValues = new LinkedHashSet<>(oldValues); 75 + DiscreteResources newValues = oldValues.add(addedValues);
85 - newValues.addAll(addedValues);
86 return childMap.replace(key, oldValues, newValues); 76 return childMap.replace(key, oldValues, newValues);
87 } 77 }
88 78
...@@ -100,20 +90,19 @@ class TransactionalDiscreteResourceSubStore { ...@@ -100,20 +90,19 @@ class TransactionalDiscreteResourceSubStore {
100 return false; 90 return false;
101 } 91 }
102 92
103 - Set<DiscreteResource> oldValues = childMap.putIfAbsent(key, new LinkedHashSet<>()); 93 + DiscreteResources oldValues = childMap.putIfAbsent(key, DiscreteResources.empty());
104 if (oldValues == null) { 94 if (oldValues == null) {
105 log.trace("No-Op removing values. key {} did not exist", key); 95 log.trace("No-Op removing values. key {} did not exist", key);
106 return true; 96 return true;
107 } 97 }
108 98
109 - if (values.stream().allMatch(x -> !oldValues.contains(x))) { 99 + if (!oldValues.containsAny(values)) {
110 // don't write map because none of the values are stored 100 // don't write map because none of the values are stored
111 log.trace("No-Op removing values. key {} did not contain {}", key, values); 101 log.trace("No-Op removing values. key {} did not contain {}", key, values);
112 return true; 102 return true;
113 } 103 }
114 104
115 - LinkedHashSet<DiscreteResource> newValues = new LinkedHashSet<>(oldValues); 105 + DiscreteResources newValues = oldValues.remove(values);
116 - newValues.removeAll(values);
117 return childMap.replace(key, oldValues, newValues); 106 return childMap.replace(key, oldValues, newValues);
118 } 107 }
119 108
......