| Index: third_party/protobuf/java/src/main/java/com/google/protobuf/SmallSortedMap.java
|
| diff --git a/third_party/protobuf/java/src/main/java/com/google/protobuf/SmallSortedMap.java b/third_party/protobuf/java/src/main/java/com/google/protobuf/SmallSortedMap.java
|
| deleted file mode 100644
|
| index c6cad6afb0e6bf1ab877c7869cb8d1e61b1aa444..0000000000000000000000000000000000000000
|
| --- a/third_party/protobuf/java/src/main/java/com/google/protobuf/SmallSortedMap.java
|
| +++ /dev/null
|
| @@ -1,618 +0,0 @@
|
| -// Protocol Buffers - Google's data interchange format
|
| -// Copyright 2008 Google Inc. All rights reserved.
|
| -// http://code.google.com/p/protobuf/
|
| -//
|
| -// Redistribution and use in source and binary forms, with or without
|
| -// modification, are permitted provided that the following conditions are
|
| -// met:
|
| -//
|
| -// * Redistributions of source code must retain the above copyright
|
| -// notice, this list of conditions and the following disclaimer.
|
| -// * Redistributions in binary form must reproduce the above
|
| -// copyright notice, this list of conditions and the following disclaimer
|
| -// in the documentation and/or other materials provided with the
|
| -// distribution.
|
| -// * Neither the name of Google Inc. nor the names of its
|
| -// contributors may be used to endorse or promote products derived from
|
| -// this software without specific prior written permission.
|
| -//
|
| -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| -
|
| -package com.google.protobuf;
|
| -
|
| -import java.util.AbstractMap;
|
| -import java.util.AbstractSet;
|
| -import java.util.ArrayList;
|
| -import java.util.Collections;
|
| -import java.util.Iterator;
|
| -import java.util.TreeMap;
|
| -import java.util.List;
|
| -import java.util.Map;
|
| -import java.util.NoSuchElementException;
|
| -import java.util.Set;
|
| -import java.util.SortedMap;
|
| -
|
| -/**
|
| - * A custom map implementation from FieldDescriptor to Object optimized to
|
| - * minimize the number of memory allocations for instances with a small number
|
| - * of mappings. The implementation stores the first {@code k} mappings in an
|
| - * array for a configurable value of {@code k}, allowing direct access to the
|
| - * corresponding {@code Entry}s without the need to create an Iterator. The
|
| - * remaining entries are stored in an overflow map. Iteration over the entries
|
| - * in the map should be done as follows:
|
| - *
|
| - * <pre> {@code
|
| - * for (int i = 0; i < fieldMap.getNumArrayEntries(); i++) {
|
| - * process(fieldMap.getArrayEntryAt(i));
|
| - * }
|
| - * for (Map.Entry<K, V> entry : fieldMap.getOverflowEntries()) {
|
| - * process(entry);
|
| - * }
|
| - * }</pre>
|
| - *
|
| - * The resulting iteration is in order of ascending field tag number. The
|
| - * object returned by {@link #entrySet()} adheres to the same contract but is
|
| - * less efficient as it necessarily involves creating an object for iteration.
|
| - * <p>
|
| - * The tradeoff for this memory efficiency is that the worst case running time
|
| - * of the {@code put()} operation is {@code O(k + lg n)}, which happens when
|
| - * entries are added in descending order. {@code k} should be chosen such that
|
| - * it covers enough common cases without adversely affecting larger maps. In
|
| - * practice, the worst case scenario does not happen for extensions because
|
| - * extension fields are serialized and deserialized in order of ascending tag
|
| - * number, but the worst case scenario can happen for DynamicMessages.
|
| - * <p>
|
| - * The running time for all other operations is similar to that of
|
| - * {@code TreeMap}.
|
| - * <p>
|
| - * Instances are not thread-safe until {@link #makeImmutable()} is called,
|
| - * after which any modifying operation will result in an
|
| - * {@link UnsupportedOperationException}.
|
| - *
|
| - * @author darick@google.com Darick Tong
|
| - */
|
| -// This class is final for all intents and purposes because the constructor is
|
| -// private. However, the FieldDescriptor-specific logic is encapsulated in
|
| -// a subclass to aid testability of the core logic.
|
| -class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
|
| -
|
| - /**
|
| - * Creates a new instance for mapping FieldDescriptors to their values.
|
| - * The {@link #makeImmutable()} implementation will convert the List values
|
| - * of any repeated fields to unmodifiable lists.
|
| - *
|
| - * @param arraySize The size of the entry array containing the
|
| - * lexicographically smallest mappings.
|
| - */
|
| - static <FieldDescriptorType extends
|
| - FieldSet.FieldDescriptorLite<FieldDescriptorType>>
|
| - SmallSortedMap<FieldDescriptorType, Object> newFieldMap(int arraySize) {
|
| - return new SmallSortedMap<FieldDescriptorType, Object>(arraySize) {
|
| - @Override
|
| - @SuppressWarnings("unchecked")
|
| - public void makeImmutable() {
|
| - if (!isImmutable()) {
|
| - for (int i = 0; i < getNumArrayEntries(); i++) {
|
| - final Map.Entry<FieldDescriptorType, Object> entry =
|
| - getArrayEntryAt(i);
|
| - if (entry.getKey().isRepeated()) {
|
| - final List value = (List) entry.getValue();
|
| - entry.setValue(Collections.unmodifiableList(value));
|
| - }
|
| - }
|
| - for (Map.Entry<FieldDescriptorType, Object> entry :
|
| - getOverflowEntries()) {
|
| - if (entry.getKey().isRepeated()) {
|
| - final List value = (List) entry.getValue();
|
| - entry.setValue(Collections.unmodifiableList(value));
|
| - }
|
| - }
|
| - }
|
| - super.makeImmutable();
|
| - }
|
| - };
|
| - }
|
| -
|
| - /**
|
| - * Creates a new instance for testing.
|
| - *
|
| - * @param arraySize The size of the entry array containing the
|
| - * lexicographically smallest mappings.
|
| - */
|
| - static <K extends Comparable<K>, V> SmallSortedMap<K, V> newInstanceForTest(
|
| - int arraySize) {
|
| - return new SmallSortedMap<K, V>(arraySize);
|
| - }
|
| -
|
| - private final int maxArraySize;
|
| - // The "entry array" is actually a List because generic arrays are not
|
| - // allowed. ArrayList also nicely handles the entry shifting on inserts and
|
| - // removes.
|
| - private List<Entry> entryList;
|
| - private Map<K, V> overflowEntries;
|
| - private boolean isImmutable;
|
| - // The EntrySet is a stateless view of the Map. It's initialized the first
|
| - // time it is requested and reused henceforth.
|
| - private volatile EntrySet lazyEntrySet;
|
| -
|
| - /**
|
| - * @code arraySize Size of the array in which the lexicographically smallest
|
| - * mappings are stored. (i.e. the {@code k} referred to in the class
|
| - * documentation).
|
| - */
|
| - private SmallSortedMap(int arraySize) {
|
| - this.maxArraySize = arraySize;
|
| - this.entryList = Collections.emptyList();
|
| - this.overflowEntries = Collections.emptyMap();
|
| - }
|
| -
|
| - /** Make this map immutable from this point forward. */
|
| - public void makeImmutable() {
|
| - if (!isImmutable) {
|
| - // Note: There's no need to wrap the entryList in an unmodifiableList
|
| - // because none of the list's accessors are exposed. The iterator() of
|
| - // overflowEntries, on the other hand, is exposed so it must be made
|
| - // unmodifiable.
|
| - overflowEntries = overflowEntries.isEmpty() ?
|
| - Collections.<K, V>emptyMap() :
|
| - Collections.unmodifiableMap(overflowEntries);
|
| - isImmutable = true;
|
| - }
|
| - }
|
| -
|
| - /** @return Whether {@link #makeImmutable()} has been called. */
|
| - public boolean isImmutable() {
|
| - return isImmutable;
|
| - }
|
| -
|
| - /** @return The number of entries in the entry array. */
|
| - public int getNumArrayEntries() {
|
| - return entryList.size();
|
| - }
|
| -
|
| - /** @return The array entry at the given {@code index}. */
|
| - public Map.Entry<K, V> getArrayEntryAt(int index) {
|
| - return entryList.get(index);
|
| - }
|
| -
|
| - /** @return There number of overflow entries. */
|
| - public int getNumOverflowEntries() {
|
| - return overflowEntries.size();
|
| - }
|
| -
|
| - /** @return An iterable over the overflow entries. */
|
| - public Iterable<Map.Entry<K, V>> getOverflowEntries() {
|
| - return overflowEntries.isEmpty() ?
|
| - EmptySet.<Map.Entry<K, V>>iterable() :
|
| - overflowEntries.entrySet();
|
| - }
|
| -
|
| - @Override
|
| - public int size() {
|
| - return entryList.size() + overflowEntries.size();
|
| - }
|
| -
|
| - /**
|
| - * The implementation throws a {@code ClassCastException} if o is not an
|
| - * object of type {@code K}.
|
| - *
|
| - * {@inheritDoc}
|
| - */
|
| - @Override
|
| - public boolean containsKey(Object o) {
|
| - @SuppressWarnings("unchecked")
|
| - final K key = (K) o;
|
| - return binarySearchInArray(key) >= 0 || overflowEntries.containsKey(key);
|
| - }
|
| -
|
| - /**
|
| - * The implementation throws a {@code ClassCastException} if o is not an
|
| - * object of type {@code K}.
|
| - *
|
| - * {@inheritDoc}
|
| - */
|
| - @Override
|
| - public V get(Object o) {
|
| - @SuppressWarnings("unchecked")
|
| - final K key = (K) o;
|
| - final int index = binarySearchInArray(key);
|
| - if (index >= 0) {
|
| - return entryList.get(index).getValue();
|
| - }
|
| - return overflowEntries.get(key);
|
| - }
|
| -
|
| - @Override
|
| - public V put(K key, V value) {
|
| - checkMutable();
|
| - final int index = binarySearchInArray(key);
|
| - if (index >= 0) {
|
| - // Replace existing array entry.
|
| - return entryList.get(index).setValue(value);
|
| - }
|
| - ensureEntryArrayMutable();
|
| - final int insertionPoint = -(index + 1);
|
| - if (insertionPoint >= maxArraySize) {
|
| - // Put directly in overflow.
|
| - return getOverflowEntriesMutable().put(key, value);
|
| - }
|
| - // Insert new Entry in array.
|
| - if (entryList.size() == maxArraySize) {
|
| - // Shift the last array entry into overflow.
|
| - final Entry lastEntryInArray = entryList.remove(maxArraySize - 1);
|
| - getOverflowEntriesMutable().put(lastEntryInArray.getKey(),
|
| - lastEntryInArray.getValue());
|
| - }
|
| - entryList.add(insertionPoint, new Entry(key, value));
|
| - return null;
|
| - }
|
| -
|
| - @Override
|
| - public void clear() {
|
| - checkMutable();
|
| - if (!entryList.isEmpty()) {
|
| - entryList.clear();
|
| - }
|
| - if (!overflowEntries.isEmpty()) {
|
| - overflowEntries.clear();
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * The implementation throws a {@code ClassCastException} if o is not an
|
| - * object of type {@code K}.
|
| - *
|
| - * {@inheritDoc}
|
| - */
|
| - @Override
|
| - public V remove(Object o) {
|
| - checkMutable();
|
| - @SuppressWarnings("unchecked")
|
| - final K key = (K) o;
|
| - final int index = binarySearchInArray(key);
|
| - if (index >= 0) {
|
| - return removeArrayEntryAt(index);
|
| - }
|
| - // overflowEntries might be Collections.unmodifiableMap(), so only
|
| - // call remove() if it is non-empty.
|
| - if (overflowEntries.isEmpty()) {
|
| - return null;
|
| - } else {
|
| - return overflowEntries.remove(key);
|
| - }
|
| - }
|
| -
|
| - private V removeArrayEntryAt(int index) {
|
| - checkMutable();
|
| - final V removed = entryList.remove(index).getValue();
|
| - if (!overflowEntries.isEmpty()) {
|
| - // Shift the first entry in the overflow to be the last entry in the
|
| - // array.
|
| - final Iterator<Map.Entry<K, V>> iterator =
|
| - getOverflowEntriesMutable().entrySet().iterator();
|
| - entryList.add(new Entry(iterator.next()));
|
| - iterator.remove();
|
| - }
|
| - return removed;
|
| - }
|
| -
|
| - /**
|
| - * @param key The key to find in the entry array.
|
| - * @return The returned integer position follows the same semantics as the
|
| - * value returned by {@link java.util.Arrays#binarySearch()}.
|
| - */
|
| - private int binarySearchInArray(K key) {
|
| - int left = 0;
|
| - int right = entryList.size() - 1;
|
| -
|
| - // Optimization: For the common case in which entries are added in
|
| - // ascending tag order, check the largest element in the array before
|
| - // doing a full binary search.
|
| - if (right >= 0) {
|
| - int cmp = key.compareTo(entryList.get(right).getKey());
|
| - if (cmp > 0) {
|
| - return -(right + 2); // Insert point is after "right".
|
| - } else if (cmp == 0) {
|
| - return right;
|
| - }
|
| - }
|
| -
|
| - while (left <= right) {
|
| - int mid = (left + right) / 2;
|
| - int cmp = key.compareTo(entryList.get(mid).getKey());
|
| - if (cmp < 0) {
|
| - right = mid - 1;
|
| - } else if (cmp > 0) {
|
| - left = mid + 1;
|
| - } else {
|
| - return mid;
|
| - }
|
| - }
|
| - return -(left + 1);
|
| - }
|
| -
|
| - /**
|
| - * Similar to the AbstractMap implementation of {@code keySet()} and
|
| - * {@code values()}, the entry set is created the first time this method is
|
| - * called, and returned in response to all subsequent calls.
|
| - *
|
| - * {@inheritDoc}
|
| - */
|
| - @Override
|
| - public Set<Map.Entry<K, V>> entrySet() {
|
| - if (lazyEntrySet == null) {
|
| - lazyEntrySet = new EntrySet();
|
| - }
|
| - return lazyEntrySet;
|
| - }
|
| -
|
| - /**
|
| - * @throws UnsupportedOperationException if {@link #makeImmutable()} has
|
| - * has been called.
|
| - */
|
| - private void checkMutable() {
|
| - if (isImmutable) {
|
| - throw new UnsupportedOperationException();
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * @return a {@link SortedMap} to which overflow entries mappings can be
|
| - * added or removed.
|
| - * @throws UnsupportedOperationException if {@link #makeImmutable()} has been
|
| - * called.
|
| - */
|
| - @SuppressWarnings("unchecked")
|
| - private SortedMap<K, V> getOverflowEntriesMutable() {
|
| - checkMutable();
|
| - if (overflowEntries.isEmpty() && !(overflowEntries instanceof TreeMap)) {
|
| - overflowEntries = new TreeMap<K, V>();
|
| - }
|
| - return (SortedMap<K, V>) overflowEntries;
|
| - }
|
| -
|
| - /**
|
| - * Lazily creates the entry list. Any code that adds to the list must first
|
| - * call this method.
|
| - */
|
| - private void ensureEntryArrayMutable() {
|
| - checkMutable();
|
| - if (entryList.isEmpty() && !(entryList instanceof ArrayList)) {
|
| - entryList = new ArrayList<Entry>(maxArraySize);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Entry implementation that implements Comparable in order to support
|
| - * binary search within the entry array. Also checks mutability in
|
| - * {@link #setValue()}.
|
| - */
|
| - private class Entry implements Map.Entry<K, V>, Comparable<Entry> {
|
| -
|
| - private final K key;
|
| - private V value;
|
| -
|
| - Entry(Map.Entry<K, V> copy) {
|
| - this(copy.getKey(), copy.getValue());
|
| - }
|
| -
|
| - Entry(K key, V value) {
|
| - this.key = key;
|
| - this.value = value;
|
| - }
|
| -
|
| - //@Override (Java 1.6 override semantics, but we must support 1.5)
|
| - public K getKey() {
|
| - return key;
|
| - }
|
| -
|
| - //@Override (Java 1.6 override semantics, but we must support 1.5)
|
| - public V getValue() {
|
| - return value;
|
| - }
|
| -
|
| - //@Override (Java 1.6 override semantics, but we must support 1.5)
|
| - public int compareTo(Entry other) {
|
| - return getKey().compareTo(other.getKey());
|
| - }
|
| -
|
| - //@Override (Java 1.6 override semantics, but we must support 1.5)
|
| - public V setValue(V newValue) {
|
| - checkMutable();
|
| - final V oldValue = this.value;
|
| - this.value = newValue;
|
| - return oldValue;
|
| - }
|
| -
|
| - @Override
|
| - public boolean equals(Object o) {
|
| - if (o == this) {
|
| - return true;
|
| - }
|
| - if (!(o instanceof Map.Entry)) {
|
| - return false;
|
| - }
|
| - @SuppressWarnings("unchecked")
|
| - Map.Entry<?, ?> other = (Map.Entry<?, ?>) o;
|
| - return equals(key, other.getKey()) && equals(value, other.getValue());
|
| - }
|
| -
|
| - @Override
|
| - public int hashCode() {
|
| - return (key == null ? 0 : key.hashCode()) ^
|
| - (value == null ? 0 : value.hashCode());
|
| - }
|
| -
|
| - @Override
|
| - public String toString() {
|
| - return key + "=" + value;
|
| - }
|
| -
|
| - /** equals() that handles null values. */
|
| - private boolean equals(Object o1, Object o2) {
|
| - return o1 == null ? o2 == null : o1.equals(o2);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Stateless view of the entries in the field map.
|
| - */
|
| - private class EntrySet extends AbstractSet<Map.Entry<K, V>> {
|
| -
|
| - @Override
|
| - public Iterator<Map.Entry<K, V>> iterator() {
|
| - return new EntryIterator();
|
| - }
|
| -
|
| - @Override
|
| - public int size() {
|
| - return SmallSortedMap.this.size();
|
| - }
|
| -
|
| - /**
|
| - * Throws a {@link ClassCastException} if o is not of the expected type.
|
| - *
|
| - * {@inheritDoc}
|
| - */
|
| - @Override
|
| - public boolean contains(Object o) {
|
| - @SuppressWarnings("unchecked")
|
| - final Map.Entry<K, V> entry = (Map.Entry<K, V>) o;
|
| - final V existing = get(entry.getKey());
|
| - final V value = entry.getValue();
|
| - return existing == value ||
|
| - (existing != null && existing.equals(value));
|
| - }
|
| -
|
| - @Override
|
| - public boolean add(Map.Entry<K, V> entry) {
|
| - if (!contains(entry)) {
|
| - put(entry.getKey(), entry.getValue());
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - /**
|
| - * Throws a {@link ClassCastException} if o is not of the expected type.
|
| - *
|
| - * {@inheritDoc}
|
| - */
|
| - @Override
|
| - public boolean remove(Object o) {
|
| - @SuppressWarnings("unchecked")
|
| - final Map.Entry<K, V> entry = (Map.Entry<K, V>) o;
|
| - if (contains(entry)) {
|
| - SmallSortedMap.this.remove(entry.getKey());
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - @Override
|
| - public void clear() {
|
| - SmallSortedMap.this.clear();
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Iterator implementation that switches from the entry array to the overflow
|
| - * entries appropriately.
|
| - */
|
| - private class EntryIterator implements Iterator<Map.Entry<K, V>> {
|
| -
|
| - private int pos = -1;
|
| - private boolean nextCalledBeforeRemove;
|
| - private Iterator<Map.Entry<K, V>> lazyOverflowIterator;
|
| -
|
| - //@Override (Java 1.6 override semantics, but we must support 1.5)
|
| - public boolean hasNext() {
|
| - return (pos + 1) < entryList.size() ||
|
| - getOverflowIterator().hasNext();
|
| - }
|
| -
|
| - //@Override (Java 1.6 override semantics, but we must support 1.5)
|
| - public Map.Entry<K, V> next() {
|
| - nextCalledBeforeRemove = true;
|
| - // Always increment pos so that we know whether the last returned value
|
| - // was from the array or from overflow.
|
| - if (++pos < entryList.size()) {
|
| - return entryList.get(pos);
|
| - }
|
| - return getOverflowIterator().next();
|
| - }
|
| -
|
| - //@Override (Java 1.6 override semantics, but we must support 1.5)
|
| - public void remove() {
|
| - if (!nextCalledBeforeRemove) {
|
| - throw new IllegalStateException("remove() was called before next()");
|
| - }
|
| - nextCalledBeforeRemove = false;
|
| - checkMutable();
|
| -
|
| - if (pos < entryList.size()) {
|
| - removeArrayEntryAt(pos--);
|
| - } else {
|
| - getOverflowIterator().remove();
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * It is important to create the overflow iterator only after the array
|
| - * entries have been iterated over because the overflow entry set changes
|
| - * when the client calls remove() on the array entries, which invalidates
|
| - * any existing iterators.
|
| - */
|
| - private Iterator<Map.Entry<K, V>> getOverflowIterator() {
|
| - if (lazyOverflowIterator == null) {
|
| - lazyOverflowIterator = overflowEntries.entrySet().iterator();
|
| - }
|
| - return lazyOverflowIterator;
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Helper class that holds immutable instances of an Iterable/Iterator that
|
| - * we return when the overflow entries is empty. This eliminates the creation
|
| - * of an Iterator object when there is nothing to iterate over.
|
| - */
|
| - private static class EmptySet {
|
| -
|
| - private static final Iterator<Object> ITERATOR = new Iterator<Object>() {
|
| - //@Override (Java 1.6 override semantics, but we must support 1.5)
|
| - public boolean hasNext() {
|
| - return false;
|
| - }
|
| - //@Override (Java 1.6 override semantics, but we must support 1.5)
|
| - public Object next() {
|
| - throw new NoSuchElementException();
|
| - }
|
| - //@Override (Java 1.6 override semantics, but we must support 1.5)
|
| - public void remove() {
|
| - throw new UnsupportedOperationException();
|
| - }
|
| - };
|
| -
|
| - private static final Iterable<Object> ITERABLE = new Iterable<Object>() {
|
| - //@Override (Java 1.6 override semantics, but we must support 1.5)
|
| - public Iterator<Object> iterator() {
|
| - return ITERATOR;
|
| - }
|
| - };
|
| -
|
| - @SuppressWarnings("unchecked")
|
| - static <T> Iterable<T> iterable() {
|
| - return (Iterable<T>) ITERABLE;
|
| - }
|
| - }
|
| -}
|
|
|