| /* |
| * Copyright 2016-present Open Networking Laboratory |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.onosproject.store.resource.impl; |
| |
| import com.google.common.base.MoreObjects; |
| import com.google.common.collect.DiscreteDomain; |
| import com.google.common.collect.Range; |
| import com.google.common.collect.RangeSet; |
| import com.google.common.collect.TreeRangeSet; |
| import org.onlab.util.Tools; |
| import org.onosproject.net.resource.DiscreteResource; |
| import org.onosproject.net.resource.DiscreteResourceCodec; |
| import org.onosproject.net.resource.DiscreteResourceId; |
| import org.onosproject.net.resource.Resources; |
| |
| import java.util.LinkedHashSet; |
| import java.util.Objects; |
| import java.util.Set; |
| import java.util.stream.Collectors; |
| import java.util.stream.IntStream; |
| |
| import static com.google.common.base.Preconditions.checkArgument; |
| |
| /** |
| * Represents discrete resources encoded by a codec. |
| */ |
| final class EncodedDiscreteResources { |
| private final RangeSet<Integer> rangeSet; |
| private final DiscreteResourceCodec codec; |
| |
| EncodedDiscreteResources(RangeSet<Integer> rangeSet, DiscreteResourceCodec codec) { |
| this.rangeSet = rangeSet; |
| this.codec = codec; |
| } |
| |
| static EncodedDiscreteResources of(Set<DiscreteResource> resources, DiscreteResourceCodec codec) { |
| RangeSet<Integer> rangeSet = TreeRangeSet.create(); |
| resources.stream() |
| .map(x -> x.valueAs(Object.class)) |
| .flatMap(Tools::stream) |
| .map(x -> codec.encode(x)) |
| .map(Range::singleton) |
| .map(x -> x.canonical(DiscreteDomain.integers())) |
| .forEach(rangeSet::add); |
| |
| return new EncodedDiscreteResources(rangeSet, codec); |
| } |
| |
| RangeSet<Integer> rangeSet() { |
| return rangeSet; |
| } |
| |
| DiscreteResourceCodec codec() { |
| return codec; |
| } |
| |
| Set<DiscreteResource> values(DiscreteResourceId parent) { |
| return rangeSet.asRanges().stream() |
| .flatMapToInt(x1 -> IntStream.range(x1.lowerEndpoint(), x1.upperEndpoint())) |
| .boxed() |
| .map(x -> codec.decode(x)) |
| .map(x -> Resources.discrete(parent, x).resource()) |
| .collect(Collectors.toCollection(LinkedHashSet::new)); |
| } |
| |
| Class<?> encodedClass() { |
| Range<Integer> firstRange = rangeSet.asRanges().iterator().next(); |
| return codec.decode(firstRange.lowerEndpoint()).getClass(); |
| } |
| |
| @SuppressWarnings("unchecked") |
| boolean contains(DiscreteResource resource) { |
| return resource.valueAs(Object.class) |
| .map(x -> codec.encode(x)) |
| .map(rangeSet::contains) |
| .orElse(false); |
| } |
| |
| EncodedDiscreteResources difference(EncodedDiscreteResources other) { |
| checkArgument(this.codec.getClass() == other.codec.getClass()); |
| |
| RangeSet<Integer> newRangeSet = TreeRangeSet.create(this.rangeSet); |
| newRangeSet.removeAll(other.rangeSet); |
| |
| return new EncodedDiscreteResources(newRangeSet, this.codec); |
| } |
| |
| EncodedDiscreteResources add(EncodedDiscreteResources other) { |
| checkArgument(this.codec.getClass() == other.codec.getClass()); |
| |
| RangeSet<Integer> newRangeSet = TreeRangeSet.create(this.rangeSet); |
| newRangeSet.addAll(other.rangeSet); |
| |
| return new EncodedDiscreteResources(newRangeSet, this.codec); |
| } |
| |
| boolean isEmpty() { |
| return rangeSet.isEmpty(); |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hash(rangeSet, codec); |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (this == obj) { |
| return true; |
| } |
| if (obj == null || getClass() != obj.getClass()) { |
| return false; |
| } |
| final EncodedDiscreteResources other = (EncodedDiscreteResources) obj; |
| return Objects.equals(this.rangeSet, other.rangeSet) |
| && Objects.equals(this.codec, other.codec); |
| } |
| |
| @Override |
| public String toString() { |
| return MoreObjects.toStringHelper(this) |
| .add("rangeSet", rangeSet) |
| .add("codec", codec) |
| .toString(); |
| } |
| } |