Committed by
Sho Shimizu
Compaction of discrete resources with range based representation
This resolves ONOS-4281 Change-Id: I0739ba94cc0b3ce617e2db44307fef396dcfb942 (cherry picked from commit 34e2c1c2)
Showing
6 changed files
with
60 additions
and
38 deletions
... | @@ -23,6 +23,7 @@ import org.apache.felix.scr.annotations.Reference; | ... | @@ -23,6 +23,7 @@ import org.apache.felix.scr.annotations.Reference; |
23 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 23 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
24 | import org.apache.felix.scr.annotations.Service; | 24 | import org.apache.felix.scr.annotations.Service; |
25 | import org.onlab.util.Tools; | 25 | import org.onlab.util.Tools; |
26 | +import org.onlab.util.KryoNamespace; | ||
26 | import org.onosproject.net.resource.ContinuousResource; | 27 | import org.onosproject.net.resource.ContinuousResource; |
27 | import org.onosproject.net.resource.ContinuousResourceId; | 28 | import org.onosproject.net.resource.ContinuousResourceId; |
28 | import org.onosproject.net.resource.DiscreteResource; | 29 | import org.onosproject.net.resource.DiscreteResource; |
... | @@ -45,7 +46,6 @@ import org.onosproject.store.service.TransactionContext; | ... | @@ -45,7 +46,6 @@ import org.onosproject.store.service.TransactionContext; |
45 | import org.slf4j.Logger; | 46 | import org.slf4j.Logger; |
46 | import org.slf4j.LoggerFactory; | 47 | import org.slf4j.LoggerFactory; |
47 | 48 | ||
48 | -import java.util.Arrays; | ||
49 | import java.util.Collection; | 49 | import java.util.Collection; |
50 | import java.util.LinkedHashMap; | 50 | import java.util.LinkedHashMap; |
51 | import java.util.List; | 51 | import java.util.List; |
... | @@ -70,11 +70,14 @@ public class ConsistentResourceStore extends AbstractStore<ResourceEvent, Resour | ... | @@ -70,11 +70,14 @@ public class ConsistentResourceStore extends AbstractStore<ResourceEvent, Resour |
70 | implements ResourceStore { | 70 | implements ResourceStore { |
71 | private static final Logger log = LoggerFactory.getLogger(ConsistentResourceStore.class); | 71 | private static final Logger log = LoggerFactory.getLogger(ConsistentResourceStore.class); |
72 | 72 | ||
73 | - static final Serializer SERIALIZER = Serializer.using( | 73 | + static final Serializer SERIALIZER = Serializer.using(KryoNamespace.newBuilder() |
74 | - Arrays.asList(KryoNamespaces.API), | 74 | + .register(KryoNamespaces.API) |
75 | - UnifiedDiscreteResources.class, | 75 | + .register(UnifiedDiscreteResources.class) |
76 | - NonEncodableDiscreteResources.class, | 76 | + .register(new EncodableDiscreteResourcesSerializer(), EncodableDiscreteResources.class) |
77 | - ContinuousResourceAllocation.class); | 77 | + .register(NonEncodableDiscreteResources.class) |
78 | + .register(EmptyDiscreteResources.class) | ||
79 | + .register(ContinuousResourceAllocation.class) | ||
80 | + .build()); | ||
78 | 81 | ||
79 | // TODO: We should provide centralized values for this | 82 | // TODO: We should provide centralized values for this |
80 | static final int MAX_RETRIES = 5; | 83 | static final int MAX_RETRIES = 5; | ... | ... |
... | @@ -32,7 +32,7 @@ interface DiscreteResources { | ... | @@ -32,7 +32,7 @@ interface DiscreteResources { |
32 | * @return a empty set. | 32 | * @return a empty set. |
33 | */ | 33 | */ |
34 | static DiscreteResources empty() { | 34 | static DiscreteResources empty() { |
35 | - return UnifiedDiscreteResources.empty(); | 35 | + return EmptyDiscreteResources.INSTANCE; |
36 | } | 36 | } |
37 | 37 | ||
38 | /** | 38 | /** |
... | @@ -41,7 +41,7 @@ interface DiscreteResources { | ... | @@ -41,7 +41,7 @@ interface DiscreteResources { |
41 | * @param resources resources | 41 | * @param resources resources |
42 | * @return instance | 42 | * @return instance |
43 | */ | 43 | */ |
44 | - static DiscreteResources of(List<DiscreteResource> resources) { | 44 | + static DiscreteResources of(Set<DiscreteResource> resources) { |
45 | return UnifiedDiscreteResources.of(resources); | 45 | return UnifiedDiscreteResources.of(resources); |
46 | } | 46 | } |
47 | 47 | ... | ... |
... | @@ -43,6 +43,10 @@ final class EncodableDiscreteResources implements DiscreteResources { | ... | @@ -43,6 +43,10 @@ final class EncodableDiscreteResources implements DiscreteResources { |
43 | } | 43 | } |
44 | 44 | ||
45 | static DiscreteResources of(Set<DiscreteResource> resources) { | 45 | static DiscreteResources of(Set<DiscreteResource> resources) { |
46 | + if (resources.isEmpty()) { | ||
47 | + return DiscreteResources.empty(); | ||
48 | + } | ||
49 | + | ||
46 | DiscreteResource parent = resources.iterator().next().parent().get(); | 50 | DiscreteResource parent = resources.iterator().next().parent().get(); |
47 | return of(parent, resources); | 51 | return of(parent, resources); |
48 | } | 52 | } | ... | ... |
core/store/dist/src/main/java/org/onosproject/store/resource/impl/NonEncodableDiscreteResources.java
... | @@ -30,26 +30,23 @@ import java.util.Set; | ... | @@ -30,26 +30,23 @@ import java.util.Set; |
30 | final class NonEncodableDiscreteResources implements DiscreteResources { | 30 | final class NonEncodableDiscreteResources implements DiscreteResources { |
31 | private final Set<DiscreteResource> values; | 31 | private final Set<DiscreteResource> values; |
32 | 32 | ||
33 | - static NonEncodableDiscreteResources empty() { | 33 | + static DiscreteResources of(Set<DiscreteResource> resources) { |
34 | - return new NonEncodableDiscreteResources(); | 34 | + if (resources.isEmpty()) { |
35 | - } | 35 | + return DiscreteResources.empty(); |
36 | + } | ||
36 | 37 | ||
37 | - static NonEncodableDiscreteResources of(List<DiscreteResource> resources) { | ||
38 | return new NonEncodableDiscreteResources(resources); | 38 | return new NonEncodableDiscreteResources(resources); |
39 | } | 39 | } |
40 | 40 | ||
41 | - private NonEncodableDiscreteResources() { | ||
42 | - this.values = new LinkedHashSet<>(); | ||
43 | - } | ||
44 | - | ||
45 | - private NonEncodableDiscreteResources(List<DiscreteResource> values) { | ||
46 | - this.values = new LinkedHashSet<>(values); | ||
47 | - } | ||
48 | - | ||
49 | private NonEncodableDiscreteResources(Set<DiscreteResource> values) { | 41 | private NonEncodableDiscreteResources(Set<DiscreteResource> values) { |
50 | this.values = values; | 42 | this.values = values; |
51 | } | 43 | } |
52 | 44 | ||
45 | + // for serializer | ||
46 | + private NonEncodableDiscreteResources() { | ||
47 | + this.values = null; | ||
48 | + } | ||
49 | + | ||
53 | @Override | 50 | @Override |
54 | public Optional<DiscreteResource> lookup(DiscreteResourceId id) { | 51 | public Optional<DiscreteResource> lookup(DiscreteResourceId id) { |
55 | DiscreteResource resource = Resources.discrete(id).resource(); | 52 | DiscreteResource resource = Resources.discrete(id).resource(); | ... | ... |
... | @@ -24,6 +24,7 @@ import org.onosproject.store.service.TransactionalMap; | ... | @@ -24,6 +24,7 @@ import org.onosproject.store.service.TransactionalMap; |
24 | import org.slf4j.Logger; | 24 | import org.slf4j.Logger; |
25 | import org.slf4j.LoggerFactory; | 25 | import org.slf4j.LoggerFactory; |
26 | 26 | ||
27 | +import java.util.LinkedHashSet; | ||
27 | import java.util.List; | 28 | import java.util.List; |
28 | import java.util.Optional; | 29 | import java.util.Optional; |
29 | 30 | ||
... | @@ -59,7 +60,7 @@ class TransactionalDiscreteResourceSubStore { | ... | @@ -59,7 +60,7 @@ class TransactionalDiscreteResourceSubStore { |
59 | return true; | 60 | return true; |
60 | } | 61 | } |
61 | 62 | ||
62 | - DiscreteResources requested = DiscreteResources.of(values); | 63 | + DiscreteResources requested = DiscreteResources.of(new LinkedHashSet<>(values)); |
63 | DiscreteResources oldValues = childMap.putIfAbsent(key, requested); | 64 | DiscreteResources oldValues = childMap.putIfAbsent(key, requested); |
64 | if (oldValues == null) { | 65 | if (oldValues == null) { |
65 | return true; | 66 | return true; | ... | ... |
... | @@ -15,12 +15,18 @@ | ... | @@ -15,12 +15,18 @@ |
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; | ||
18 | import org.onosproject.net.resource.DiscreteResource; | 19 | import org.onosproject.net.resource.DiscreteResource; |
19 | import org.onosproject.net.resource.DiscreteResourceId; | 20 | import org.onosproject.net.resource.DiscreteResourceId; |
21 | +import org.onosproject.net.resource.Resources; | ||
20 | 22 | ||
23 | +import java.util.LinkedHashSet; | ||
21 | import java.util.List; | 24 | import java.util.List; |
25 | +import java.util.Map; | ||
22 | import java.util.Optional; | 26 | import java.util.Optional; |
23 | import java.util.Set; | 27 | import java.util.Set; |
28 | +import java.util.stream.Collectors; | ||
29 | +import java.util.stream.Stream; | ||
24 | 30 | ||
25 | /** | 31 | /** |
26 | * Represents a set of resources containing resources that can be encoded as integer | 32 | * Represents a set of resources containing resources that can be encoded as integer |
... | @@ -28,55 +34,66 @@ import java.util.Set; | ... | @@ -28,55 +34,66 @@ import java.util.Set; |
28 | */ | 34 | */ |
29 | final class UnifiedDiscreteResources implements DiscreteResources { | 35 | final class UnifiedDiscreteResources implements DiscreteResources { |
30 | private final DiscreteResources nonEncodables; | 36 | private final DiscreteResources nonEncodables; |
37 | + private final DiscreteResources encodables; | ||
38 | + private static final Codecs CODECS = Codecs.getInstance(); | ||
31 | 39 | ||
32 | - static DiscreteResources empty() { | 40 | + static DiscreteResources of(Set<DiscreteResource> resources) { |
33 | - return new UnifiedDiscreteResources(); | 41 | + if (resources.isEmpty()) { |
34 | - } | 42 | + return DiscreteResources.empty(); |
35 | - | 43 | + } |
36 | - static DiscreteResources of(List<DiscreteResource> resources) { | ||
37 | - return new UnifiedDiscreteResources(resources); | ||
38 | - } | ||
39 | 44 | ||
40 | - private UnifiedDiscreteResources() { | 45 | + Map<Boolean, Set<DiscreteResource>> partitioned = resources.stream() |
41 | - this.nonEncodables = NonEncodableDiscreteResources.empty(); | 46 | + .collect(Collectors.partitioningBy(CODECS::isEncodable, Collectors.toCollection(LinkedHashSet::new))); |
47 | + return new UnifiedDiscreteResources( | ||
48 | + NonEncodableDiscreteResources.of(partitioned.get(false)), | ||
49 | + EncodableDiscreteResources.of(partitioned.get(true)) | ||
50 | + ); | ||
42 | } | 51 | } |
43 | 52 | ||
44 | - private UnifiedDiscreteResources(List<DiscreteResource> resources) { | 53 | + private UnifiedDiscreteResources(DiscreteResources nonEncodables, DiscreteResources encodables) { |
45 | - this.nonEncodables = NonEncodableDiscreteResources.of(resources); | 54 | + this.nonEncodables = nonEncodables; |
55 | + this.encodables = encodables; | ||
46 | } | 56 | } |
47 | 57 | ||
48 | @Override | 58 | @Override |
49 | public Optional<DiscreteResource> lookup(DiscreteResourceId id) { | 59 | public Optional<DiscreteResource> lookup(DiscreteResourceId id) { |
60 | + if (CODECS.isEncodable(Resources.discrete(id).resource())) { | ||
61 | + return encodables.lookup(id); | ||
62 | + } | ||
63 | + | ||
50 | return nonEncodables.lookup(id); | 64 | return nonEncodables.lookup(id); |
51 | } | 65 | } |
52 | 66 | ||
53 | @Override | 67 | @Override |
54 | public DiscreteResources difference(DiscreteResources other) { | 68 | public DiscreteResources difference(DiscreteResources other) { |
55 | - return nonEncodables.difference(other); | 69 | + return of(Sets.difference(values(), other.values())); |
56 | } | 70 | } |
57 | 71 | ||
58 | @Override | 72 | @Override |
59 | public boolean isEmpty() { | 73 | public boolean isEmpty() { |
60 | - return nonEncodables.isEmpty(); | 74 | + return nonEncodables.isEmpty() && encodables.isEmpty(); |
61 | } | 75 | } |
62 | 76 | ||
63 | @Override | 77 | @Override |
64 | public boolean containsAny(List<DiscreteResource> other) { | 78 | public boolean containsAny(List<DiscreteResource> other) { |
65 | - return nonEncodables.containsAny(other); | 79 | + Map<Boolean, List<DiscreteResource>> partitioned = other.stream() |
80 | + .collect(Collectors.partitioningBy(CODECS::isEncodable)); | ||
81 | + return nonEncodables.containsAny(partitioned.get(false)) || encodables.containsAny(partitioned.get(true)); | ||
66 | } | 82 | } |
67 | 83 | ||
68 | @Override | 84 | @Override |
69 | public DiscreteResources add(DiscreteResources other) { | 85 | public DiscreteResources add(DiscreteResources other) { |
70 | - return nonEncodables.add(other); | 86 | + return of(Sets.union(this.values(), other.values())); |
71 | } | 87 | } |
72 | 88 | ||
73 | @Override | 89 | @Override |
74 | public DiscreteResources remove(List<DiscreteResource> removed) { | 90 | public DiscreteResources remove(List<DiscreteResource> removed) { |
75 | - return nonEncodables.remove(removed); | 91 | + return of(Sets.difference(values(), new LinkedHashSet<>(removed))); |
76 | } | 92 | } |
77 | 93 | ||
78 | @Override | 94 | @Override |
79 | public Set<DiscreteResource> values() { | 95 | public Set<DiscreteResource> values() { |
80 | - return nonEncodables.values(); | 96 | + return Stream.concat(encodables.values().stream(), nonEncodables.values().stream()) |
97 | + .collect(Collectors.toCollection(LinkedHashSet::new)); | ||
81 | } | 98 | } |
82 | } | 99 | } | ... | ... |
-
Please register or login to post a comment