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 com.google.common.base.Preconditions;
11 import com.google.common.collect.AbstractIterator;
12 import com.google.common.collect.ImmutableList;
13 import java.util.AbstractCollection;
14 import java.util.Arrays;
15 import java.util.Collection;
16 import java.util.Iterator;
17 import java.util.function.Consumer;
18 import javax.annotation.Nonnull;
19 import javax.annotation.Nullable;
22 * Simple integer-to-StatementContextBase map optimized for size and restricted in scope of operations. It does not
23 * implement {@link java.util.Map} for simplicity's sake.
25 * @author Robert Varga
27 abstract class StatementMap {
28 private static final class Empty extends StatementMap {
30 StatementContextBase<?, ?, ?> get(final int index) {
35 StatementMap put(final int index, final StatementContextBase<?, ?, ?> object) {
36 return index == 0 ? new Singleton(object) : new Regular(index, object);
40 Collection<StatementContextBase<?, ?, ?>> values() {
41 return ImmutableList.of();
50 private static final class Regular extends StatementMap {
51 private StatementContextBase<?, ?, ?>[] elements;
53 Regular(final int index, final StatementContextBase<?, ?, ?> object) {
54 elements = new StatementContextBase<?, ?, ?>[index + 1];
55 elements[index] = Preconditions.checkNotNull(object);
58 Regular(final StatementContextBase<?, ?, ?> object0, final int index,
59 final StatementContextBase<?, ?, ?> object) {
60 elements = new StatementContextBase<?, ?, ?>[index + 1];
61 elements[0] = Preconditions.checkNotNull(object0);
62 elements[index] = Preconditions.checkNotNull(object);
66 StatementContextBase<?, ?, ?> get(final int index) {
67 if (index >= elements.length) {
71 return elements[index];
75 StatementMap put(final int index, final StatementContextBase<?, ?, ?> object) {
76 if (index < elements.length) {
77 Preconditions.checkArgument(elements[index] == null);
79 elements = Arrays.copyOf(elements, index + 1);
82 elements[index] = Preconditions.checkNotNull(object);
87 Collection<StatementContextBase<?, ?, ?>> values() {
88 return new RegularAsCollection<>(elements);
93 return countElements(elements);
97 static int countElements(final Object[] elements) {
98 // Optimized for non-sparse case
100 for (Object e : elements) {
106 return elements.length - nulls;
109 private static final class RegularAsCollection<T> extends AbstractCollection<T> {
110 private final T[] elements;
112 RegularAsCollection(final T[] elements) {
113 this.elements = Preconditions.checkNotNull(elements);
117 public void forEach(final Consumer<? super T> action) {
118 for (T e : elements) {
126 public boolean isEmpty() {
127 // This has a single-use and when it is instantiated, we know to have at least two items
132 public Iterator<T> iterator() {
133 return new AbstractIterator<T>() {
134 private int nextOffset = 0;
137 protected T computeNext() {
138 while (nextOffset < elements.length) {
139 final T ret = elements[nextOffset++];
152 return countElements(elements);
156 private static final class Singleton extends StatementMap {
157 private final StatementContextBase<?, ?, ?> object;
159 Singleton(final StatementContextBase<?, ?, ?> object) {
160 this.object = Preconditions.checkNotNull(object);
164 StatementContextBase<?, ?, ?> get(final int index) {
165 return index == 0 ? object : null;
169 StatementMap put(final int index, final StatementContextBase<?, ?, ?> object) {
170 Preconditions.checkArgument(index != 0);
171 return new Regular(this.object, index, object);
175 Collection<StatementContextBase<?, ?, ?>> values() {
176 return ImmutableList.of(object);
185 private static final StatementMap EMPTY = new Empty();
187 static StatementMap empty() {
192 * Return the statement context at specified index.
194 * @param index Element index, must be non-negative
195 * @return Requested element or null if there is no element at that index
197 abstract @Nullable StatementContextBase<?, ?, ?> get(int index);
200 * Add a statement at specified index.
202 * @param index Element index, must be non-negative
203 * @param object Object to store
204 * @return New statement map
205 * @throws IllegalArgumentException if the index is already occupied
207 abstract @Nonnull StatementMap put(int index, @Nonnull StatementContextBase<?, ?, ?> object);
210 * Return a read-only view of the elements in this map. Unlike other maps, this view does not detect concurrent
211 * modification. Iteration is performed in order of increasing offset. In face of concurrent modification, number
212 * of elements returned through iteration may not match the size reported via {@link Collection#size()}.
214 * @return Read-only view of available statements.
216 abstract @Nonnull Collection<StatementContextBase<?, ?, ?>> values();