2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.collect.AbstractIterator;
14 import com.google.common.collect.ImmutableList;
15 import java.util.AbstractCollection;
16 import java.util.Arrays;
17 import java.util.Collection;
18 import java.util.Iterator;
19 import java.util.function.Consumer;
20 import javax.annotation.Nonnull;
21 import javax.annotation.Nullable;
24 * Simple integer-to-StatementContextBase map optimized for size and restricted in scope of operations. It does not
25 * implement {@link java.util.Map} for simplicity's sake.
27 * @author Robert Varga
29 abstract class StatementMap {
30 private static final class Empty extends StatementMap {
32 StatementContextBase<?, ?, ?> get(final int index) {
37 StatementMap put(final int index, final StatementContextBase<?, ?, ?> obj) {
38 return index == 0 ? new Singleton(obj) : new Regular(index, obj);
42 Collection<StatementContextBase<?, ?, ?>> values() {
43 return ImmutableList.of();
52 StatementMap ensureCapacity(final int expectedLimit) {
53 return expectedLimit < 2 ? this : new Regular(expectedLimit);
62 private static final class Regular extends StatementMap {
63 private StatementContextBase<?, ?, ?>[] elements;
66 Regular(final int expectedLimit) {
67 elements = new StatementContextBase<?, ?, ?>[expectedLimit];
70 Regular(final int index, final StatementContextBase<?, ?, ?> object) {
71 this(index + 1, index, object);
74 Regular(final StatementContextBase<?, ?, ?> object0, final int index,
75 final StatementContextBase<?, ?, ?> object) {
76 this(index + 1, 0, object0);
77 elements[index] = requireNonNull(object);
81 Regular(final int expectedLimit, final int index, final StatementContextBase<?, ?, ?> object) {
83 elements[index] = requireNonNull(object);
88 StatementContextBase<?, ?, ?> get(final int index) {
89 if (index >= elements.length) {
93 return elements[index];
97 StatementMap put(final int index, final StatementContextBase<?, ?, ?> obj) {
98 if (index < elements.length) {
99 checkArgument(elements[index] == null);
101 // FIXME: detect linear growth
102 elements = Arrays.copyOf(elements, index + 1);
105 elements[index] = requireNonNull(obj);
111 Collection<StatementContextBase<?, ?, ?>> values() {
112 return new RegularAsCollection<>(elements, size);
121 StatementMap ensureCapacity(final int expectedLimit) {
122 if (elements.length < expectedLimit) {
123 elements = Arrays.copyOf(elements, expectedLimit);
130 return elements.length;
134 private static final class RegularAsCollection<T> extends AbstractCollection<T> {
135 private final T[] elements;
136 private final int size;
138 RegularAsCollection(final T[] elements, final int size) {
139 this.elements = requireNonNull(elements);
144 public void forEach(final Consumer<? super T> action) {
145 for (T e : elements) {
153 public Iterator<T> iterator() {
154 return new AbstractIterator<T>() {
155 private int nextOffset = 0;
158 protected T computeNext() {
159 while (nextOffset < elements.length) {
160 final T ret = elements[nextOffset++];
177 private static final class Singleton extends StatementMap {
178 private final StatementContextBase<?, ?, ?> object;
180 Singleton(final StatementContextBase<?, ?, ?> object) {
181 this.object = requireNonNull(object);
185 StatementContextBase<?, ?, ?> get(final int index) {
186 return index == 0 ? object : null;
190 StatementMap put(final int index, final StatementContextBase<?, ?, ?> obj) {
191 checkArgument(index != 0);
192 return new Regular(this.object, index, obj);
196 Collection<StatementContextBase<?, ?, ?>> values() {
197 return ImmutableList.of(object);
206 StatementMap ensureCapacity(final int expectedLimit) {
207 return expectedLimit < 2 ? this : new Regular(expectedLimit, 0, object);
216 private static final StatementMap EMPTY = new Empty();
218 static StatementMap empty() {
223 * Return the statement context at specified index.
225 * @param index Element index, must be non-negative
226 * @return Requested element or null if there is no element at that index
228 abstract @Nullable StatementContextBase<?, ?, ?> get(int index);
231 * Add a statement at specified index.
233 * @param index Element index, must be non-negative
234 * @param obj Object to store
235 * @return New statement map
236 * @throws IllegalArgumentException if the index is already occupied
238 abstract @Nonnull StatementMap put(int index, @Nonnull StatementContextBase<?, ?, ?> obj);
241 * Return a read-only view of the elements in this map. Unlike other maps, this view does not detect concurrent
242 * modification. Iteration is performed in order of increasing offset. In face of concurrent modification, number
243 * of elements returned through iteration may not match the size reported via {@link Collection#size()}.
245 * @return Read-only view of available statements.
247 abstract @Nonnull Collection<StatementContextBase<?, ?, ?>> values();
251 abstract StatementMap ensureCapacity(int expectedLimit);
253 abstract int capacity();