blob: 00ad671dac21a67e2e7d6a25ade2e5ab58c01c49 [file] [log] [blame]
Sho SHIMIZU22fb2832016-05-06 11:44:03 -07001/*
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 */
16package org.onosproject.store.resource.impl;
17
18import com.google.common.collect.ImmutableList;
19import com.google.common.collect.ImmutableSet;
Sho SHIMIZU22fb2832016-05-06 11:44:03 -070020import org.onlab.util.GuavaCollectors;
21import org.onlab.util.Tools;
22import org.onosproject.net.resource.ContinuousResource;
23import org.onosproject.net.resource.ContinuousResourceId;
24import org.onosproject.net.resource.DiscreteResourceId;
25import org.onosproject.net.resource.Resource;
26import org.onosproject.net.resource.ResourceAllocation;
27import org.onosproject.net.resource.ResourceConsumer;
28import org.onosproject.store.service.ConsistentMap;
29import org.onosproject.store.service.ConsistentMapException;
30import org.onosproject.store.service.StorageService;
31import org.onosproject.store.service.TransactionContext;
32import org.onosproject.store.service.Versioned;
33
34import java.util.LinkedHashSet;
35import java.util.List;
36import java.util.Set;
37import java.util.stream.Stream;
38
Sho SHIMIZU22fb2832016-05-06 11:44:03 -070039import static org.onosproject.store.resource.impl.ConsistentResourceStore.MAX_RETRIES;
40import static org.onosproject.store.resource.impl.ConsistentResourceStore.RETRY_DELAY;
41import static org.onosproject.store.resource.impl.ConsistentResourceStore.SERIALIZER;
42import static org.onosproject.store.resource.impl.ResourceStoreUtil.hasEnoughResource;
43
44class ConsistentContinuousResourceStore {
45 private ConsistentMap<ContinuousResourceId, ContinuousResourceAllocation> consumers;
46 private ConsistentMap<DiscreteResourceId, Set<ContinuousResource>> childMap;
47
48 ConsistentContinuousResourceStore(StorageService service) {
49 this.consumers = service.<ContinuousResourceId, ContinuousResourceAllocation>consistentMapBuilder()
50 .withName(MapNames.CONTINUOUS_CONSUMER_MAP)
51 .withSerializer(SERIALIZER)
52 .build();
53 this.childMap = service.<DiscreteResourceId, Set<ContinuousResource>>consistentMapBuilder()
54 .withName(MapNames.CONTINUOUS_CHILD_MAP)
55 .withSerializer(SERIALIZER)
56 .build();
57
58 Tools.retryable(() -> childMap.put(Resource.ROOT.id(), new LinkedHashSet<>()),
59 ConsistentMapException.class, MAX_RETRIES, RETRY_DELAY);
60 }
61
62 TransactionalContinuousResourceStore transactional(TransactionContext tx) {
63 return new TransactionalContinuousResourceStore(tx);
64 }
65
66 // computational complexity: O(n) where n is the number of the existing allocations for the resource
67 List<ResourceAllocation> getResourceAllocations(ContinuousResourceId resource) {
68 Versioned<ContinuousResourceAllocation> allocations = consumers.get(resource);
69 if (allocations == null) {
70 return ImmutableList.of();
71 }
72
73 return allocations.value().allocations().stream()
74 .filter(x -> x.resource().id().equals(resource))
75 .collect(GuavaCollectors.toImmutableList());
76 }
77
78 Set<ContinuousResource> getChildResources(DiscreteResourceId parent) {
79 Versioned<Set<ContinuousResource>> children = childMap.get(parent);
80
81 if (children == null) {
82 return ImmutableSet.of();
83 }
84
85 return children.value();
86 }
87
88 public boolean isAvailable(ContinuousResource resource) {
89 // check if it's registered or not.
90 Versioned<Set<ContinuousResource>> children = childMap.get(resource.parent().get().id());
91 if (children == null) {
92 return false;
93 }
94
95 ContinuousResource registered = children.value().stream()
96 .filter(c -> c.id().equals(resource.id()))
97 .findFirst()
98 .get();
99 if (registered.value() < resource.value()) {
100 // Capacity < requested, can never satisfy
101 return false;
102 }
103
104 // check if there's enough left
105 Versioned<ContinuousResourceAllocation> allocation = consumers.get(resource.id());
106 if (allocation == null) {
107 // no allocation (=no consumer) full registered resources available
108 return true;
109 }
110
111 return hasEnoughResource(allocation.value().original(), resource, allocation.value());
112 }
113
114 <T> Stream<ContinuousResource> getAllocatedResources(DiscreteResourceId parent, Class<T> cls) {
115 Set<ContinuousResource> children = getChildResources(parent);
116 if (children.isEmpty()) {
117 return Stream.of();
118 }
119
120 return children.stream()
121 .filter(x -> x.id().equals(parent.child(cls)))
122 // we don't use cascading simple predicates like follows to reduce accesses to consistent map
123 // .filter(x -> continuousConsumers.containsKey(x.id()))
124 // .filter(x -> continuousConsumers.get(x.id()) != null)
125 // .filter(x -> !continuousConsumers.get(x.id()).value().allocations().isEmpty());
126 .filter(resource -> {
127 Versioned<ContinuousResourceAllocation> allocation = consumers.get(resource.id());
128 if (allocation == null) {
129 return false;
130 }
131 return !allocation.value().allocations().isEmpty();
132 });
133 }
134
135 Stream<ContinuousResource> getResources(ResourceConsumer consumer) {
136 return consumers.values().stream()
Sho SHIMIZUe99af222016-05-12 11:47:48 -0700137 .flatMap(x -> x.value().allocations().stream())
138 .filter(x -> x.consumer().equals(consumer))
139 // this cast is safe because this class stores
140 // continuous resource allocations only
141 .map(x -> (ContinuousResource) x.resource());
Sho SHIMIZU22fb2832016-05-06 11:44:03 -0700142 }
143}