import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
-import com.google.common.base.Preconditions;
import com.google.common.collect.AbstractIterator;
import com.google.common.collect.ImmutableList;
import java.util.AbstractCollection;
import java.util.Collection;
import java.util.Iterator;
import java.util.function.Consumer;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
/**
* Simple integer-to-StatementContextBase map optimized for size and restricted in scope of operations. It does not
}
@Override
- StatementMap put(final int index, final StatementContextBase<?, ?, ?> object) {
- return index == 0 ? new Singleton(object) : new Regular(index, object);
+ StatementMap put(final int index, final StatementContextBase<?, ?, ?> obj) {
+ return index == 0 ? new Singleton(obj) : new Regular(index, obj);
}
@Override
int size() {
return 0;
}
+
+ @Override
+ StatementMap ensureCapacity(final int expectedLimit) {
+ return expectedLimit < 2 ? this : new Regular(expectedLimit);
+ }
+
+ @Override
+ int capacity() {
+ return 0;
+ }
}
private static final class Regular extends StatementMap {
private StatementContextBase<?, ?, ?>[] elements;
+ private int size;
+
+ Regular(final int expectedLimit) {
+ elements = new StatementContextBase<?, ?, ?>[expectedLimit];
+ }
Regular(final int index, final StatementContextBase<?, ?, ?> object) {
- elements = new StatementContextBase<?, ?, ?>[index + 1];
- elements[index] = requireNonNull(object);
+ this(index + 1, index, object);
}
Regular(final StatementContextBase<?, ?, ?> object0, final int index,
final StatementContextBase<?, ?, ?> object) {
- elements = new StatementContextBase<?, ?, ?>[index + 1];
- elements[0] = requireNonNull(object0);
+ this(index + 1, 0, object0);
+ elements[index] = requireNonNull(object);
+ size = 2;
+ }
+
+ Regular(final int expectedLimit, final int index, final StatementContextBase<?, ?, ?> object) {
+ this(expectedLimit);
elements[index] = requireNonNull(object);
+ size = 1;
}
@Override
StatementContextBase<?, ?, ?> get(final int index) {
- if (index >= elements.length) {
- return null;
- }
-
- return elements[index];
+ return index >= elements.length ? null : elements[index];
}
@Override
- StatementMap put(final int index, final StatementContextBase<?, ?, ?> object) {
+ StatementMap put(final int index, final StatementContextBase<?, ?, ?> obj) {
if (index < elements.length) {
checkArgument(elements[index] == null);
} else {
+ // FIXME: detect linear growth
elements = Arrays.copyOf(elements, index + 1);
}
- elements[index] = requireNonNull(object);
+ elements[index] = requireNonNull(obj);
+ size++;
return this;
}
@Override
Collection<StatementContextBase<?, ?, ?>> values() {
- return new RegularAsCollection<>(elements);
+ return new RegularAsCollection<>(elements, size);
}
@Override
int size() {
- return countElements(elements);
+ return size;
}
- }
- static int countElements(final Object[] elements) {
- // Optimized for non-sparse case
- int nulls = 0;
- for (Object e : elements) {
- if (e == null) {
- nulls++;
+ @Override
+ StatementMap ensureCapacity(final int expectedLimit) {
+ if (elements.length < expectedLimit) {
+ elements = Arrays.copyOf(elements, expectedLimit);
}
+ return this;
}
- return elements.length - nulls;
+ @Override
+ int capacity() {
+ return elements.length;
+ }
}
private static final class RegularAsCollection<T> extends AbstractCollection<T> {
private final T[] elements;
+ private final int size;
- RegularAsCollection(final T[] elements) {
- this.elements = Preconditions.checkNotNull(elements);
+ RegularAsCollection(final T[] elements, final int size) {
+ this.elements = requireNonNull(elements);
+ this.size = size;
}
@Override
}
}
- @Override
- public boolean isEmpty() {
- // This has a single-use and when it is instantiated, we know to have at least two items
- return false;
- }
-
@Override
public Iterator<T> iterator() {
return new AbstractIterator<T>() {
@Override
public int size() {
- return countElements(elements);
+ return size;
}
}
}
@Override
- StatementMap put(final int index, final StatementContextBase<?, ?, ?> object) {
+ StatementMap put(final int index, final StatementContextBase<?, ?, ?> obj) {
checkArgument(index != 0);
- return new Regular(this.object, index, object);
+ return new Regular(this.object, index, obj);
}
@Override
int size() {
return 1;
}
+
+ @Override
+ StatementMap ensureCapacity(final int expectedLimit) {
+ return expectedLimit < 2 ? this : new Regular(expectedLimit, 0, object);
+ }
+
+ @Override
+ int capacity() {
+ return 1;
+ }
}
private static final StatementMap EMPTY = new Empty();
* Add a statement at specified index.
*
* @param index Element index, must be non-negative
- * @param object Object to store
+ * @param obj Object to store
* @return New statement map
* @throws IllegalArgumentException if the index is already occupied
*/
- abstract @Nonnull StatementMap put(int index, @Nonnull StatementContextBase<?, ?, ?> object);
+ abstract @NonNull StatementMap put(int index, @NonNull StatementContextBase<?, ?, ?> obj);
/**
* Return a read-only view of the elements in this map. Unlike other maps, this view does not detect concurrent
*
* @return Read-only view of available statements.
*/
- abstract @Nonnull Collection<StatementContextBase<?, ?, ?>> values();
+ abstract @NonNull Collection<StatementContextBase<?, ?, ?>> values();
abstract int size();
+
+ abstract @NonNull StatementMap ensureCapacity(int expectedLimit);
+
+ abstract int capacity();
}