core: Remove com.google.common.collect usages for Android
This reduces the number of methods gRPC brings in by ~450, which is
substantial. Each application will see different numbers though,
depending on their usage and their other dependencies.
A very rough (under) counting for number of methods included because of
gRPC in android-interop-test is 2746, and that is reduced to 2313 (-433)
by this change. That count includes grpc, guava, okhttp, okio, and nano.
The actual reduction of methods is 447, with the discrepency due to
reduction of methods in java.util and java.lang. Of the 433 removed
methods, 377 are from com.google.common.collect and 61 from
com.google.common.base. The removal costed an increase of 5 methods
(total 1671) within io.grpc itself.
diff --git a/compiler/src/java_plugin/cpp/java_generator.cpp b/compiler/src/java_plugin/cpp/java_generator.cpp
index 05262e0..5ccbe4d 100644
--- a/compiler/src/java_plugin/cpp/java_generator.cpp
+++ b/compiler/src/java_plugin/cpp/java_generator.cpp
@@ -1130,16 +1130,11 @@
vars["ServiceDescriptor"] =
"io.grpc.ServiceDescriptor";
vars["AbstractStub"] = "io.grpc.stub.AbstractStub";
- vars["ImmutableList"] = "com.google.common.collect.ImmutableList";
- vars["Collection"] = "java.util.Collection";
vars["MethodDescriptor"] = "io.grpc.MethodDescriptor";
vars["NanoUtils"] = "io.grpc.protobuf.nano.NanoUtils";
vars["StreamObserver"] = "io.grpc.stub.StreamObserver";
vars["Iterator"] = "java.util.Iterator";
- vars["Map"] = "java.util.Map";
- vars["TimeUnit"] = "java.util.concurrent.TimeUnit";
vars["Generated"] = "javax.annotation.Generated";
- vars["Immutable"] = "javax.annotation.concurrent.Immutable";
vars["ListenableFuture"] =
"com.google.common.util.concurrent.ListenableFuture";
vars["ExperimentalApi"] = "io.grpc.ExperimentalApi";
diff --git a/core/src/main/java/io/grpc/Metadata.java b/core/src/main/java/io/grpc/Metadata.java
index 962c0c2..26a418b 100644
--- a/core/src/main/java/io/grpc/Metadata.java
+++ b/core/src/main/java/io/grpc/Metadata.java
@@ -36,14 +36,13 @@
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collections;
+import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
@@ -202,19 +201,12 @@
* parsed as T or null if there are none. The iterator is not guaranteed to be "live." It may or
* may not be accurate if Metadata is mutated.
*/
- public <T> Iterable<T> getAll(final Key<T> key) {
+ public <T> Iterable<T> getAll(Key<T> key) {
if (containsKey(key)) {
/* This is unmodifiable currently, but could be made to support remove() in the future. If
* removal support is added, the {@link #storeCount} variable needs to be updated
* appropriately. */
- return Iterables.unmodifiableIterable(Iterables.transform(
- store.get(key.name()),
- new Function<MetadataEntry, T>() {
- @Override
- public T apply(MetadataEntry entry) {
- return entry.getParsed(key);
- }
- }));
+ return new ValueIterable<T>(key, store.get(key.name()));
}
return null;
}
@@ -270,18 +262,13 @@
/**
* Remove all values for the given key. If there were no values, {@code null} is returned.
*/
- public <T> Iterable<T> removeAll(final Key<T> key) {
+ public <T> Iterable<T> removeAll(Key<T> key) {
List<MetadataEntry> values = store.remove(key.name());
if (values == null) {
return null;
}
storeCount -= values.size();
- return Iterables.transform(values, new Function<MetadataEntry, T>() {
- @Override
- public T apply(MetadataEntry metadataEntry) {
- return metadataEntry.getParsed(key);
- }
- });
+ return new ValueIterable<T>(key, values);
}
/**
@@ -694,4 +681,35 @@
}
}
}
+
+ private static class ValueIterable<T> implements Iterable<T> {
+ private final Key<T> key;
+ private final Iterable<MetadataEntry> entries;
+
+ public ValueIterable(Key<T> key, Iterable<MetadataEntry> entries) {
+ this.key = key;
+ this.entries = entries;
+ }
+
+ @Override
+ public Iterator<T> iterator() {
+ final Iterator<MetadataEntry> iterator = entries.iterator();
+ class ValueIterator implements Iterator<T> {
+ @Override public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ @Override public T next() {
+ return iterator.next().getParsed(key);
+ }
+
+ @Override public void remove() {
+ // Not implemented to not need to conditionally update {@link #storeCount}.
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ return new ValueIterator();
+ }
+ }
}
diff --git a/core/src/main/java/io/grpc/ServerServiceDefinition.java b/core/src/main/java/io/grpc/ServerServiceDefinition.java
index 088cb65..43b71e3 100644
--- a/core/src/main/java/io/grpc/ServerServiceDefinition.java
+++ b/core/src/main/java/io/grpc/ServerServiceDefinition.java
@@ -35,10 +35,9 @@
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
-import com.google.common.collect.ImmutableMap;
-
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -55,12 +54,13 @@
}
private final ServiceDescriptor serviceDescriptor;
- private final ImmutableMap<String, ServerMethodDefinition<?, ?>> methods;
+ private final Map<String, ServerMethodDefinition<?, ?>> methods;
private ServerServiceDefinition(
ServiceDescriptor serviceDescriptor, Map<String, ServerMethodDefinition<?, ?>> methods) {
this.serviceDescriptor = checkNotNull(serviceDescriptor, "serviceDescriptor");
- this.methods = ImmutableMap.copyOf(methods);
+ this.methods = Collections.unmodifiableMap(
+ new HashMap<String, ServerMethodDefinition<?, ?>>(methods));
}
/**
diff --git a/core/src/main/java/io/grpc/internal/GrpcUtil.java b/core/src/main/java/io/grpc/internal/GrpcUtil.java
index ba06be5..ce0435b 100644
--- a/core/src/main/java/io/grpc/internal/GrpcUtil.java
+++ b/core/src/main/java/io/grpc/internal/GrpcUtil.java
@@ -38,7 +38,6 @@
import com.google.common.base.Splitter;
import com.google.common.base.Stopwatch;
import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
@@ -50,6 +49,12 @@
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.AbstractMap.SimpleImmutableEntry;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -485,23 +490,32 @@
@VisibleForTesting
static class TimeoutMarshaller implements Metadata.AsciiMarshaller<Long> {
- // ImmutableMap's have consistent iteration order.
- private static final ImmutableMap<Character, TimeUnit> UNITS =
- ImmutableMap.<Character, TimeUnit>builder()
- .put('n', TimeUnit.NANOSECONDS)
- .put('u', TimeUnit.MICROSECONDS)
- .put('m', TimeUnit.MILLISECONDS)
- .put('S', TimeUnit.SECONDS)
- .put('M', TimeUnit.MINUTES)
- .put('H', TimeUnit.HOURS)
- .build();
+ @SuppressWarnings("unchecked") // asList uses an array which doesn't handle generics
+ private static final List<Map.Entry<Character, TimeUnit>> SERIALIZE_ORDER
+ = Collections.unmodifiableList(Arrays.<Entry<Character, TimeUnit>>asList(
+ new SimpleImmutableEntry<Character, TimeUnit>('n', TimeUnit.NANOSECONDS),
+ new SimpleImmutableEntry<Character, TimeUnit>('u', TimeUnit.MICROSECONDS),
+ new SimpleImmutableEntry<Character, TimeUnit>('m', TimeUnit.MILLISECONDS),
+ new SimpleImmutableEntry<Character, TimeUnit>('S', TimeUnit.SECONDS),
+ new SimpleImmutableEntry<Character, TimeUnit>('M', TimeUnit.MINUTES),
+ new SimpleImmutableEntry<Character, TimeUnit>('H', TimeUnit.HOURS)));
+
+ private static final Map<Character, TimeUnit> UNITS = createUnits();
+
+ private static Map<Character, TimeUnit> createUnits() {
+ Map<Character, TimeUnit> units = new HashMap<Character, TimeUnit>();
+ for (Entry<Character, TimeUnit> unit : SERIALIZE_ORDER) {
+ units.put(unit.getKey(), unit.getValue());
+ }
+ return Collections.unmodifiableMap(units);
+ }
@Override
public String toAsciiString(Long timeoutNanos) {
checkArgument(timeoutNanos >= 0, "Negative timeout");
// the smallest integer with 9 digits
int cutoff = 100000000;
- for (Entry<Character, TimeUnit> unit : UNITS.entrySet()) {
+ for (Entry<Character, TimeUnit> unit : SERIALIZE_ORDER) {
long timeout = unit.getValue().convert(timeoutNanos, TimeUnit.NANOSECONDS);
if (timeout < cutoff) {
return Long.toString(timeout) + unit.getKey();
diff --git a/core/src/main/java/io/grpc/internal/Http2Ping.java b/core/src/main/java/io/grpc/internal/Http2Ping.java
index 150cdbd..2b4df88 100644
--- a/core/src/main/java/io/grpc/internal/Http2Ping.java
+++ b/core/src/main/java/io/grpc/internal/Http2Ping.java
@@ -32,10 +32,10 @@
package io.grpc.internal;
import com.google.common.base.Stopwatch;
-import com.google.common.collect.Maps;
import io.grpc.internal.ClientTransport.PingCallback;
+import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
@@ -68,7 +68,8 @@
/**
* The registered callbacks and the executor used to invoke them.
*/
- @GuardedBy("this") private Map<PingCallback, Executor> callbacks = Maps.newLinkedHashMap();
+ @GuardedBy("this") private Map<PingCallback, Executor> callbacks
+ = new LinkedHashMap<PingCallback, Executor>();
/**
* False until the operation completes, either successfully (other side sent acknowledgement) or
diff --git a/core/src/main/java/io/grpc/internal/InternalHandlerRegistry.java b/core/src/main/java/io/grpc/internal/InternalHandlerRegistry.java
index 72ea6b1..7a228f9 100644
--- a/core/src/main/java/io/grpc/internal/InternalHandlerRegistry.java
+++ b/core/src/main/java/io/grpc/internal/InternalHandlerRegistry.java
@@ -31,18 +31,19 @@
package io.grpc.internal;
-import com.google.common.collect.ImmutableMap;
-
import io.grpc.ServerMethodDefinition;
import io.grpc.ServerServiceDefinition;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.Map;
+
import javax.annotation.Nullable;
final class InternalHandlerRegistry {
- private final ImmutableMap<String, ServerMethodDefinition<?, ?>> methods;
+ private final Map<String, ServerMethodDefinition<?, ?>> methods;
- private InternalHandlerRegistry(ImmutableMap<String, ServerMethodDefinition<?, ?>> methods) {
+ private InternalHandlerRegistry(Map<String, ServerMethodDefinition<?, ?>> methods) {
this.methods = methods;
}
@@ -62,14 +63,14 @@
}
InternalHandlerRegistry build() {
- ImmutableMap.Builder<String, ServerMethodDefinition<?, ?>> mapBuilder =
- ImmutableMap.builder();
+ Map<String, ServerMethodDefinition<?, ?>> map =
+ new HashMap<String, ServerMethodDefinition<?, ?>>();
for (ServerServiceDefinition service : services.values()) {
for (ServerMethodDefinition<?, ?> method : service.getMethods()) {
- mapBuilder.put(method.getMethodDescriptor().getFullMethodName(), method);
+ map.put(method.getMethodDescriptor().getFullMethodName(), method);
}
}
- return new InternalHandlerRegistry(mapBuilder.build());
+ return new InternalHandlerRegistry(Collections.unmodifiableMap(map));
}
}
}
diff --git a/core/src/main/java/io/grpc/internal/RoundRobinServerList.java b/core/src/main/java/io/grpc/internal/RoundRobinServerList.java
index 7357e88..9fe8212 100644
--- a/core/src/main/java/io/grpc/internal/RoundRobinServerList.java
+++ b/core/src/main/java/io/grpc/internal/RoundRobinServerList.java
@@ -32,7 +32,6 @@
package io.grpc.internal;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterators;
import io.grpc.EquivalentAddressGroup;
@@ -40,7 +39,9 @@
import io.grpc.TransportManager;
import java.net.SocketAddress;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@@ -95,8 +96,7 @@
@NotThreadSafe
public static class Builder<T> {
- private final ImmutableList.Builder<EquivalentAddressGroup> listBuilder =
- ImmutableList.builder();
+ private final List<EquivalentAddressGroup> list = new ArrayList<EquivalentAddressGroup>();
private final TransportManager<T> tm;
public Builder(TransportManager<T> tm) {
@@ -107,7 +107,7 @@
* Adds a server to the list, or {@code null} for a drop entry.
*/
public Builder<T> addSocketAddress(@Nullable SocketAddress address) {
- listBuilder.add(new EquivalentAddressGroup(address));
+ list.add(new EquivalentAddressGroup(address));
return this;
}
@@ -117,7 +117,7 @@
* @param addresses the addresses to add
*/
public Builder<T> add(EquivalentAddressGroup addresses) {
- listBuilder.add(addresses);
+ list.add(addresses);
return this;
}
@@ -127,12 +127,13 @@
* @param addresses the list of addresses group.
*/
public Builder<T> addAll(Collection<EquivalentAddressGroup> addresses) {
- listBuilder.addAll(addresses);
+ list.addAll(addresses);
return this;
}
public RoundRobinServerList<T> build() {
- return new RoundRobinServerList<T>(tm, listBuilder.build());
+ return new RoundRobinServerList<T>(tm,
+ Collections.unmodifiableList(new ArrayList<EquivalentAddressGroup>(list)));
}
}
}
diff --git a/core/src/test/java/io/grpc/MetadataTest.java b/core/src/test/java/io/grpc/MetadataTest.java
index 2744965..e741f47 100644
--- a/core/src/test/java/io/grpc/MetadataTest.java
+++ b/core/src/test/java/io/grpc/MetadataTest.java
@@ -115,6 +115,18 @@
}
@Test
+ public void testGetAllNoRemove() {
+ Fish lance = new Fish(LANCE);
+ Metadata metadata = new Metadata();
+ metadata.put(KEY, lance);
+ Iterator<Fish> i = metadata.getAll(KEY).iterator();
+ assertSame(lance, i.next());
+
+ thrown.expect(UnsupportedOperationException.class);
+ i.remove();
+ }
+
+ @Test
public void testWriteParsed() {
Fish lance = new Fish(LANCE);
Metadata metadata = new Metadata();
diff --git a/core/src/test/java/io/grpc/ServerServiceDefinitionTest.java b/core/src/test/java/io/grpc/ServerServiceDefinitionTest.java
index dbc7c36..00611c3 100644
--- a/core/src/test/java/io/grpc/ServerServiceDefinitionTest.java
+++ b/core/src/test/java/io/grpc/ServerServiceDefinitionTest.java
@@ -161,7 +161,8 @@
.build();
assertEquals(Collections.<MethodDescriptor<?, ?>>emptyList(),
ssd.getServiceDescriptor().getMethods());
- assertEquals(Collections.<ServerMethodDefinition<?, ?>>emptySet(), ssd.getMethods());
+ assertEquals(Collections.<ServerMethodDefinition<?, ?>>emptySet(),
+ new HashSet<ServerMethodDefinition<?, ?>>(ssd.getMethods()));
}
private static class NoopServerCallHandler<ReqT, RespT>