blob: 60eed40cbc0fee14c225904c0a16c2b6eb01f90d [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;
Sho SHIMIZU22fb2832016-05-06 11:44:03 -070021import org.onosproject.net.resource.ContinuousResource;
22import org.onosproject.net.resource.ContinuousResourceId;
23import org.onosproject.net.resource.DiscreteResourceId;
24import org.onosproject.net.resource.Resource;
25import org.onosproject.net.resource.ResourceAllocation;
Naoki Shiotabd1974c2016-04-29 18:44:17 -070026import org.onosproject.net.resource.ResourceConsumerId;
Sho SHIMIZU22fb2832016-05-06 11:44:03 -070027import org.onosproject.store.service.ConsistentMap;
Sho SHIMIZU22fb2832016-05-06 11:44:03 -070028import org.onosproject.store.service.StorageService;
29import org.onosproject.store.service.TransactionContext;
30import org.onosproject.store.service.Versioned;
31
32import java.util.LinkedHashSet;
33import java.util.List;
34import java.util.Set;
Sho SHIMIZU9cc4a242016-05-26 12:55:35 -070035import java.util.stream.Collectors;
Sho SHIMIZU22fb2832016-05-06 11:44:03 -070036import java.util.stream.Stream;
37
Sho SHIMIZU22fb2832016-05-06 11:44:03 -070038import static org.onosproject.store.resource.impl.ConsistentResourceStore.SERIALIZER;
Sho SHIMIZU22fb2832016-05-06 11:44:03 -070039
Sho SHIMIZU7ecf5ea2016-05-13 15:28:59 -070040class ConsistentContinuousResourceSubStore {
Sho SHIMIZU22fb2832016-05-06 11:44:03 -070041 private ConsistentMap<ContinuousResourceId, ContinuousResourceAllocation> consumers;
42 private ConsistentMap<DiscreteResourceId, Set<ContinuousResource>> childMap;
43
Sho SHIMIZU7ecf5ea2016-05-13 15:28:59 -070044 ConsistentContinuousResourceSubStore(StorageService service) {
Sho SHIMIZU22fb2832016-05-06 11:44:03 -070045 this.consumers = service.<ContinuousResourceId, ContinuousResourceAllocation>consistentMapBuilder()
46 .withName(MapNames.CONTINUOUS_CONSUMER_MAP)
47 .withSerializer(SERIALIZER)
48 .build();
49 this.childMap = service.<DiscreteResourceId, Set<ContinuousResource>>consistentMapBuilder()
50 .withName(MapNames.CONTINUOUS_CHILD_MAP)
51 .withSerializer(SERIALIZER)
52 .build();
53
Madan Jampanic6371882016-06-03 21:30:17 -070054 childMap.put(Resource.ROOT.id(), new LinkedHashSet<>());
Sho SHIMIZU22fb2832016-05-06 11:44:03 -070055 }
56
Sho SHIMIZU7ecf5ea2016-05-13 15:28:59 -070057 TransactionalContinuousResourceSubStore transactional(TransactionContext tx) {
58 return new TransactionalContinuousResourceSubStore(tx);
Sho SHIMIZU22fb2832016-05-06 11:44:03 -070059 }
60
61 // computational complexity: O(n) where n is the number of the existing allocations for the resource
62 List<ResourceAllocation> getResourceAllocations(ContinuousResourceId resource) {
63 Versioned<ContinuousResourceAllocation> allocations = consumers.get(resource);
64 if (allocations == null) {
65 return ImmutableList.of();
66 }
67
68 return allocations.value().allocations().stream()
69 .filter(x -> x.resource().id().equals(resource))
70 .collect(GuavaCollectors.toImmutableList());
71 }
72
73 Set<ContinuousResource> getChildResources(DiscreteResourceId parent) {
74 Versioned<Set<ContinuousResource>> children = childMap.get(parent);
75
76 if (children == null) {
77 return ImmutableSet.of();
78 }
79
80 return children.value();
81 }
82
Sho SHIMIZU9cc4a242016-05-26 12:55:35 -070083 <T> Set<ContinuousResource> getChildResources(DiscreteResourceId parent, Class<T> cls) {
84 // naive implementation
85 return getChildResources(parent).stream()
86 .filter(x -> x.isTypeOf(cls))
87 .collect(Collectors.toCollection(LinkedHashSet::new));
88 }
89
Sho SHIMIZU22fb2832016-05-06 11:44:03 -070090 public boolean isAvailable(ContinuousResource resource) {
91 // check if it's registered or not.
92 Versioned<Set<ContinuousResource>> children = childMap.get(resource.parent().get().id());
93 if (children == null) {
94 return false;
95 }
96
97 ContinuousResource registered = children.value().stream()
98 .filter(c -> c.id().equals(resource.id()))
99 .findFirst()
100 .get();
101 if (registered.value() < resource.value()) {
102 // Capacity < requested, can never satisfy
103 return false;
104 }
105
106 // check if there's enough left
107 Versioned<ContinuousResourceAllocation> allocation = consumers.get(resource.id());
108 if (allocation == null) {
109 // no allocation (=no consumer) full registered resources available
110 return true;
111 }
112
Sho SHIMIZU38bcfcf2016-05-13 15:48:54 -0700113 return allocation.value().hasEnoughResource(resource);
Sho SHIMIZU22fb2832016-05-06 11:44:03 -0700114 }
115
116 <T> Stream<ContinuousResource> getAllocatedResources(DiscreteResourceId parent, Class<T> cls) {
117 Set<ContinuousResource> children = getChildResources(parent);
118 if (children.isEmpty()) {
119 return Stream.of();
120 }
121
122 return children.stream()
123 .filter(x -> x.id().equals(parent.child(cls)))
124 // we don't use cascading simple predicates like follows to reduce accesses to consistent map
125 // .filter(x -> continuousConsumers.containsKey(x.id()))
126 // .filter(x -> continuousConsumers.get(x.id()) != null)
127 // .filter(x -> !continuousConsumers.get(x.id()).value().allocations().isEmpty());
128 .filter(resource -> {
129 Versioned<ContinuousResourceAllocation> allocation = consumers.get(resource.id());
130 if (allocation == null) {
131 return false;
132 }
133 return !allocation.value().allocations().isEmpty();
134 });
135 }
136
Naoki Shiotabd1974c2016-04-29 18:44:17 -0700137 Stream<ContinuousResource> getResources(ResourceConsumerId consumerId) {
Sho SHIMIZU22fb2832016-05-06 11:44:03 -0700138 return consumers.values().stream()
Sho SHIMIZUe99af222016-05-12 11:47:48 -0700139 .flatMap(x -> x.value().allocations().stream())
Naoki Shiotabd1974c2016-04-29 18:44:17 -0700140 .filter(x -> x.consumerId().equals(consumerId))
Sho SHIMIZUe99af222016-05-12 11:47:48 -0700141 // this cast is safe because this class stores
142 // continuous resource allocations only
143 .map(x -> (ContinuousResource) x.resource());
Sho SHIMIZU22fb2832016-05-06 11:44:03 -0700144 }
145}