org.apache.calcite.util.CompatibleGuava11 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of calcite-core Show documentation
Show all versions of calcite-core Show documentation
Core Calcite APIs and engine.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.calcite.util;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.ForwardingSet;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Multiset;
import com.google.common.collect.Sets;
import java.util.AbstractCollection;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.NavigableMap;
import java.util.NavigableSet;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
/** Helper methods to provide modern Guava functionality based on Guava 11.
*
* @see Compatible
*/
class CompatibleGuava11 {
private CompatibleGuava11() {}
public static Map asMap(
Set set, Function super K, V> function) {
return new AsMapView(set, function);
}
/**
* {@link AbstractSet} substitute without the potentially-quadratic
* {@code removeAll} implementation.
*
* @param element type
*/
abstract static class ImprovedAbstractSet extends AbstractSet {
@Override public boolean removeAll(Collection> c) {
return removeAllImpl(this, c);
}
@Override public boolean retainAll(Collection> c) {
return super.retainAll(Objects.requireNonNull(c)); // GWT compatibility
}
}
/**
* Remove each element in an iterable from a set.
*/
static boolean removeAllImpl(Set> set, Iterator> iterator) {
boolean changed = false;
while (iterator.hasNext()) {
changed |= set.remove(iterator.next());
}
return changed;
}
static boolean removeAllImpl(Set> set, Collection> collection) {
Objects.requireNonNull(collection); // for GWT
if (collection instanceof Multiset) {
collection = ((Multiset>) collection).elementSet();
}
// AbstractSet.removeAll(List) has quadratic behavior if the list size
// is just less than the set's size. We augment the test by
// assuming that sets have fast contains() performance, and other
// collections don't. See
// http://code.google.com/p/guava-libraries/issues/detail?id=1013
if (collection instanceof Set && collection.size() > set.size()) {
Iterator> setIterator = set.iterator();
boolean changed = false;
while (setIterator.hasNext()) {
if (collection.contains(setIterator.next())) {
changed = true;
setIterator.remove();
}
}
return changed;
} else {
return removeAllImpl(set, collection.iterator());
}
}
/** ImprovedAbstractMap.
*
* @param key type
* @param value type */
abstract static class ImprovedAbstractMap extends AbstractMap {
/**
* Creates the entry set to be returned by {@link #entrySet()}. This method
* is invoked at most once on a given map, at the time when {@code entrySet}
* is first called.
*/
protected abstract Set> createEntrySet();
private Set> entrySet;
@Override public Set> entrySet() {
Set> result = entrySet;
if (result == null) {
entrySet = result = createEntrySet();
}
return result;
}
private Set keySet;
@Override public Set keySet() {
Set result = keySet;
if (result == null) {
return keySet = new KeySet() {
@Override Map map() {
return ImprovedAbstractMap.this;
}
};
}
return result;
}
private Collection values;
@Override public Collection values() {
Collection result = values;
if (result == null) {
return values = new Values() {
@Override Map map() {
return ImprovedAbstractMap.this;
}
};
}
return result;
}
}
static Iterator keyIterator(
Iterator> entryIterator) {
return new TransformedIterator, K>(entryIterator) {
@Override K transform(Map.Entry entry) {
return entry.getKey();
}
};
}
/** KeySet.
*
* @param key type
* @param value type */
abstract static class KeySet extends ImprovedAbstractSet {
abstract Map map();
@Override public Iterator iterator() {
return keyIterator(map().entrySet().iterator());
}
@Override public int size() {
return map().size();
}
@Override public boolean isEmpty() {
return map().isEmpty();
}
@Override public boolean contains(Object o) {
return map().containsKey(o);
}
@Override public boolean remove(Object o) {
if (contains(o)) {
map().remove(o);
return true;
}
return false;
}
@Override public void clear() {
map().clear();
}
}
private static Set removeOnlySet(final Set set) {
return new ForwardingSet() {
@Override protected Set delegate() {
return set;
}
@Override public boolean add(E element) {
throw new UnsupportedOperationException();
}
@Override public boolean addAll(Collection extends E> es) {
throw new UnsupportedOperationException();
}
};
}
private static Iterator> asSetEntryIterator(
Set set, final Function super K, V> function) {
return new TransformedIterator>(set.iterator()) {
@Override Map.Entry transform(K key) {
return Maps.immutableEntry(key, function.apply(key));
}
};
}
/** AsMapView.
*
* @param key type
* @param value type */
private static class AsMapView extends ImprovedAbstractMap {
private final Set set;
final Function super K, V> function;
Set backingSet() {
return set;
}
AsMapView(Set set, Function super K, V> function) {
this.set = Objects.requireNonNull(set);
this.function = Objects.requireNonNull(function);
}
@Override public Set keySet() {
// probably not worth caching
return removeOnlySet(backingSet());
}
@Override public Collection values() {
// probably not worth caching
return Collections2.transform(set, function);
}
@Override public int size() {
return backingSet().size();
}
@Override public boolean containsKey(Object key) {
return backingSet().contains(key);
}
@Override public V get(Object key) {
if (backingSet().contains(key)) {
@SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it
K k = (K) key;
return function.apply(k);
} else {
return null;
}
}
@Override public V remove(Object key) {
if (backingSet().remove(key)) {
@SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it
K k = (K) key;
return function.apply(k);
} else {
return null;
}
}
@Override public void clear() {
backingSet().clear();
}
@Override protected Set> createEntrySet() {
return new EntrySet() {
@Override Map map() {
return AsMapView.this;
}
@Override public Iterator> iterator() {
return asSetEntryIterator(backingSet(), function);
}
};
}
}
/** EntrySet.
*
* @param key type
* @param value type */
abstract static class EntrySet
extends ImprovedAbstractSet> {
abstract Map map();
@Override public int size() {
return map().size();
}
@Override public void clear() {
map().clear();
}
@Override public boolean contains(Object o) {
if (o instanceof Map.Entry) {
Map.Entry, ?> entry = (Map.Entry, ?>) o;
Object key = entry.getKey();
V value = map().get(key);
return Objects.equals(value, entry.getValue())
&& (value != null || map().containsKey(key));
}
return false;
}
@Override public boolean isEmpty() {
return map().isEmpty();
}
@Override public boolean remove(Object o) {
if (contains(o)) {
Map.Entry, ?> entry = (Map.Entry, ?>) o;
return map().keySet().remove(entry.getKey());
}
return false;
}
@Override public boolean removeAll(Collection> c) {
try {
return super.removeAll(Objects.requireNonNull(c));
} catch (UnsupportedOperationException e) {
// if the iterators don't support remove
boolean changed = true;
for (Object o : c) {
changed |= remove(o);
}
return changed;
}
}
@Override public boolean retainAll(Collection> c) {
try {
return super.retainAll(Objects.requireNonNull(c));
} catch (UnsupportedOperationException e) {
// if the iterators don't support remove
Set
© 2015 - 2024 Weber Informatics LLC | Privacy Policy