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.base.MoreObjects;
14 import com.google.common.collect.AbstractIterator;
15 import com.google.common.collect.ImmutableList;
16 import java.util.AbstractCollection;
17 import java.util.Arrays;
18 import java.util.Collection;
19 import java.util.Iterator;
20 import java.util.function.Consumer;
21 import org.eclipse.jdt.annotation.NonNull;
22 import org.eclipse.jdt.annotation.Nullable;
25 * Simple integer-to-StatementContextBase map optimized for size and restricted in scope of operations. It does not
26 * implement {@link java.util.Map} for simplicity's sake.
28 * @author Robert Varga
30 abstract class StatementMap {
31 private static final class Empty extends StatementMap {
33 AbstractResumedStatement<?, ?, ?> get(final int index) {
38 StatementMap put(final int index, final AbstractResumedStatement<?, ?, ?> obj) {
39 return index == 0 ? new Singleton(obj) : new Regular(index, obj);
43 Collection<AbstractResumedStatement<?, ?, ?>> values() {
44 return ImmutableList.of();
53 StatementMap ensureCapacity(final int expectedLimit) {
54 return expectedLimit < 2 ? this : new Regular(expectedLimit);
63 private static final class Regular extends StatementMap {
64 private AbstractResumedStatement<?, ?, ?>[] elements;
67 Regular(final int expectedLimit) {
68 elements = new AbstractResumedStatement<?, ?, ?>[expectedLimit];
71 Regular(final int index, final AbstractResumedStatement<?, ?, ?> object) {
72 this(index + 1, index, object);
75 Regular(final AbstractResumedStatement<?, ?, ?> object0, final int index,
76 final AbstractResumedStatement<?, ?, ?> object) {
77 this(index + 1, 0, object0);
78 elements[index] = requireNonNull(object);
82 Regular(final int expectedLimit, final int index, final AbstractResumedStatement<?, ?, ?> object) {
84 elements[index] = requireNonNull(object);
89 AbstractResumedStatement<?, ?, ?> get(final int index) {
90 return index >= elements.length ? null : elements[index];
94 StatementMap put(final int index, final AbstractResumedStatement<?, ?, ?> obj) {
95 if (index < elements.length) {
96 checkArgument(elements[index] == null);
98 // FIXME: detect linear growth
99 elements = Arrays.copyOf(elements, index + 1);
102 elements[index] = requireNonNull(obj);
108 Collection<AbstractResumedStatement<?, ?, ?>> values() {
109 return new RegularAsCollection<>(elements, size);
118 StatementMap ensureCapacity(final int expectedLimit) {
119 if (elements.length < expectedLimit) {
120 elements = Arrays.copyOf(elements, expectedLimit);
127 return elements.length;
131 private static final class RegularAsCollection<T> extends AbstractCollection<T> {
132 private final T[] elements;
133 private final int size;
135 RegularAsCollection(final T[] elements, final int size) {
136 this.elements = requireNonNull(elements);
141 public void forEach(final Consumer<? super T> action) {
142 for (T e : elements) {
150 public Iterator<T> iterator() {
151 return new AbstractIterator<>() {
152 private int nextOffset = 0;
155 protected T computeNext() {
156 while (nextOffset < elements.length) {
157 final T ret = elements[nextOffset++];
174 private static final class Singleton extends StatementMap {
175 private final AbstractResumedStatement<?, ?, ?> object;
177 Singleton(final AbstractResumedStatement<?, ?, ?> object) {
178 this.object = requireNonNull(object);
182 AbstractResumedStatement<?, ?, ?> get(final int index) {
183 return index == 0 ? object : null;
187 StatementMap put(final int index, final AbstractResumedStatement<?, ?, ?> obj) {
188 checkArgument(index != 0);
189 return new Regular(this.object, index, obj);
193 Collection<AbstractResumedStatement<?, ?, ?>> values() {
194 return ImmutableList.of(object);
203 StatementMap ensureCapacity(final int expectedLimit) {
204 return expectedLimit < 2 ? this : new Regular(expectedLimit, 0, object);
213 private static final StatementMap EMPTY = new Empty();
215 static StatementMap empty() {
220 * Return the statement context at specified index.
222 * @param index Element index, must be non-negative
223 * @return Requested element or null if there is no element at that index
225 abstract @Nullable AbstractResumedStatement<?, ?, ?> get(int index);
228 * Add a statement at specified index.
230 * @param index Element index, must be non-negative
231 * @param obj Object to store
232 * @return New statement map
233 * @throws IllegalArgumentException if the index is already occupied
235 abstract @NonNull StatementMap put(int index, @NonNull AbstractResumedStatement<?, ?, ?> obj);
238 * Return a read-only view of the elements in this map. Unlike other maps, this view does not detect concurrent
239 * modification. Iteration is performed in order of increasing offset. In face of concurrent modification, number
240 * of elements returned through iteration may not match the size reported via {@link Collection#size()}.
242 * @return Read-only view of available statements.
244 abstract @NonNull Collection<AbstractResumedStatement<?, ?, ?>> values();
248 abstract @NonNull StatementMap ensureCapacity(int expectedLimit);
250 abstract int capacity();
253 public final String toString() {
254 return MoreObjects.toStringHelper(StatementMap.class).add("values", values()).toString();