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.Preconditions;
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 javax.annotation.Nonnull;
22 import javax.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 StatementContextBase<?, ?, ?> get(final int index) {
38 StatementMap put(final int index, final StatementContextBase<?, ?, ?> obj) {
39 return index == 0 ? new Singleton(obj) : new Regular(index, obj);
43 Collection<StatementContextBase<?, ?, ?>> values() {
44 return ImmutableList.of();
53 private static final class Regular extends StatementMap {
54 private StatementContextBase<?, ?, ?>[] elements;
56 Regular(final int index, final StatementContextBase<?, ?, ?> object) {
57 elements = new StatementContextBase<?, ?, ?>[index + 1];
58 elements[index] = requireNonNull(object);
61 Regular(final StatementContextBase<?, ?, ?> object0, final int index,
62 final StatementContextBase<?, ?, ?> object) {
63 elements = new StatementContextBase<?, ?, ?>[index + 1];
64 elements[0] = requireNonNull(object0);
65 elements[index] = requireNonNull(object);
69 StatementContextBase<?, ?, ?> get(final int index) {
70 if (index >= elements.length) {
74 return elements[index];
78 StatementMap put(final int index, final StatementContextBase<?, ?, ?> obj) {
79 if (index < elements.length) {
80 checkArgument(elements[index] == null);
82 elements = Arrays.copyOf(elements, index + 1);
85 elements[index] = requireNonNull(obj);
90 Collection<StatementContextBase<?, ?, ?>> values() {
91 return new RegularAsCollection<>(elements);
96 return countElements(elements);
100 static int countElements(final Object[] elements) {
101 // Optimized for non-sparse case
103 for (Object e : elements) {
109 return elements.length - nulls;
112 private static final class RegularAsCollection<T> extends AbstractCollection<T> {
113 private final T[] elements;
115 RegularAsCollection(final T[] elements) {
116 this.elements = Preconditions.checkNotNull(elements);
120 public void forEach(final Consumer<? super T> action) {
121 for (T e : elements) {
129 public boolean isEmpty() {
130 // This has a single-use and when it is instantiated, we know to have at least two items
135 public Iterator<T> iterator() {
136 return new AbstractIterator<T>() {
137 private int nextOffset = 0;
140 protected T computeNext() {
141 while (nextOffset < elements.length) {
142 final T ret = elements[nextOffset++];
155 return countElements(elements);
159 private static final class Singleton extends StatementMap {
160 private final StatementContextBase<?, ?, ?> object;
162 Singleton(final StatementContextBase<?, ?, ?> object) {
163 this.object = requireNonNull(object);
167 StatementContextBase<?, ?, ?> get(final int index) {
168 return index == 0 ? object : null;
172 StatementMap put(final int index, final StatementContextBase<?, ?, ?> obj) {
173 checkArgument(index != 0);
174 return new Regular(this.object, index, obj);
178 Collection<StatementContextBase<?, ?, ?>> values() {
179 return ImmutableList.of(object);
188 private static final StatementMap EMPTY = new Empty();
190 static StatementMap empty() {
195 * Return the statement context at specified index.
197 * @param index Element index, must be non-negative
198 * @return Requested element or null if there is no element at that index
200 abstract @Nullable StatementContextBase<?, ?, ?> get(int index);
203 * Add a statement at specified index.
205 * @param index Element index, must be non-negative
206 * @param obj Object to store
207 * @return New statement map
208 * @throws IllegalArgumentException if the index is already occupied
210 abstract @Nonnull StatementMap put(int index, @Nonnull StatementContextBase<?, ?, ?> obj);
213 * Return a read-only view of the elements in this map. Unlike other maps, this view does not detect concurrent
214 * modification. Iteration is performed in order of increasing offset. In face of concurrent modification, number
215 * of elements returned through iteration may not match the size reported via {@link Collection#size()}.
217 * @return Read-only view of available statements.
219 abstract @Nonnull Collection<StatementContextBase<?, ?, ?>> values();