Use ImmutableSortedSet for small ImmutableUnsignedLongSets
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / utils / ImmutableUnsignedLongSet.java
1 /*
2  * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.cluster.datastore.utils;
9
10 import com.google.common.annotations.Beta;
11 import com.google.common.collect.ImmutableSortedSet;
12 import java.io.DataInput;
13 import java.io.DataOutput;
14 import java.io.IOException;
15 import java.util.ArrayList;
16 import java.util.NavigableSet;
17 import java.util.TreeSet;
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.opendaylight.yangtools.concepts.Immutable;
20 import org.opendaylight.yangtools.concepts.WritableObject;
21
22 @Beta
23 public final class ImmutableUnsignedLongSet extends UnsignedLongSet implements Immutable, WritableObject {
24     // Do not all
25     private static final int ARRAY_MAX_ELEMENTS = 4096;
26
27     private static final @NonNull ImmutableUnsignedLongSet EMPTY =
28         new ImmutableUnsignedLongSet(ImmutableSortedSet.of());
29
30     private ImmutableUnsignedLongSet(final NavigableSet<Entry> ranges) {
31         super(ranges);
32     }
33
34     static @NonNull ImmutableUnsignedLongSet copyOf(final MutableUnsignedLongSet mutable) {
35         if (mutable.isEmpty()) {
36             return of();
37         }
38         if (mutable.size() <= ARRAY_MAX_ELEMENTS) {
39             return new ImmutableUnsignedLongSet(ImmutableSortedSet.copyOfSorted(mutable.trustedRanges()));
40         }
41         return new ImmutableUnsignedLongSet(new TreeSet<>(mutable.trustedRanges()));
42     }
43
44     public static @NonNull ImmutableUnsignedLongSet of() {
45         return EMPTY;
46     }
47
48     @Override
49     public ImmutableUnsignedLongSet immutableCopy() {
50         return this;
51     }
52
53     public static @NonNull ImmutableUnsignedLongSet readFrom(final DataInput in) throws IOException {
54         return readFrom(in, in.readInt());
55     }
56
57     public static @NonNull ImmutableUnsignedLongSet readFrom(final DataInput in, final int size) throws IOException {
58         if (size == 0) {
59             return EMPTY;
60         }
61
62         final NavigableSet<Entry> ranges;
63         if (size <= ARRAY_MAX_ELEMENTS) {
64             final var entries = new ArrayList<Entry>(size);
65             for (int i = 0; i < size; ++i) {
66                 entries.add(Entry.readUnsigned(in));
67             }
68             ranges = ImmutableSortedSet.copyOf(entries);
69         } else {
70             ranges = new TreeSet<>();
71             for (int i = 0; i < size; ++i) {
72                 ranges.add(Entry.readUnsigned(in));
73             }
74         }
75         return new ImmutableUnsignedLongSet(ranges);
76     }
77
78     @Override
79     public void writeTo(final DataOutput out) throws IOException {
80         out.writeInt(size());
81         writeRanges(out);
82     }
83
84     public void writeRangesTo(final @NonNull DataOutput out, final int size) throws IOException {
85         if (size != size()) {
86             throw new IOException("Mismatched size: expected " + size() + ", got " + size);
87         }
88         writeRanges(out);
89     }
90
91     private void writeRanges(final @NonNull DataOutput out) throws IOException {
92         for (var range : trustedRanges()) {
93             range.writeUnsigned(out);
94         }
95     }
96 }