context: Implement equals and hashCode for Deadline (grpc#6075)
diff --git a/context/build.gradle b/context/build.gradle
index c38132a..1513cbc 100644
--- a/context/build.gradle
+++ b/context/build.gradle
@@ -1,7 +1,7 @@
description = 'gRPC: Context'
dependencies {
- testCompile libraries.jsr305
+ testCompile libraries.jsr305, libraries.guava_testlib
signature "org.codehaus.mojo.signature:java17:1.0@signature"
signature "net.sf.androidscents.signature:android-api-level-14:4.0_r4@signature"
}
diff --git a/context/src/main/java/io/grpc/Deadline.java b/context/src/main/java/io/grpc/Deadline.java
index 778bdd4..c7b50e0 100644
--- a/context/src/main/java/io/grpc/Deadline.java
+++ b/context/src/main/java/io/grpc/Deadline.java
@@ -16,6 +16,7 @@
package io.grpc;
+import java.util.Arrays;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@@ -231,6 +232,30 @@
return 0;
}
+ @Override
+ public int hashCode() {
+ return Arrays.asList(this.ticker, this.deadlineNanos).hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof Deadline)) {
+ return false;
+ }
+
+ final Deadline other = (Deadline) o;
+ if (this.ticker == null ? other.ticker != null : this.ticker != other.ticker) {
+ return false;
+ }
+ if (this.deadlineNanos != other.deadlineNanos) {
+ return false;
+ }
+ return true;
+ }
+
/**
* Time source representing nanoseconds since fixed but arbitrary point in time.
*
diff --git a/context/src/test/java/io/grpc/DeadlineTest.java b/context/src/test/java/io/grpc/DeadlineTest.java
index 5f35918..69f849b 100644
--- a/context/src/test/java/io/grpc/DeadlineTest.java
+++ b/context/src/test/java/io/grpc/DeadlineTest.java
@@ -27,6 +27,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import com.google.common.testing.EqualsTester;
import com.google.common.truth.Truth;
import java.util.Arrays;
import java.util.concurrent.Future;
@@ -310,6 +311,20 @@
assertEquals("0.000012000s from now (ticker=FAKE_TICKER)", d.toString());
}
+ @Test
+ public void equality() {
+ final Deadline d1 = Deadline.after(12, TimeUnit.MICROSECONDS, ticker);
+ final Deadline d2 = Deadline.after(12, TimeUnit.MICROSECONDS, ticker);
+ final Deadline d3 = Deadline.after(12, TimeUnit.MICROSECONDS, new FakeTicker());
+ final Deadline d4 = Deadline.after(10, TimeUnit.MICROSECONDS, ticker);
+
+ new EqualsTester()
+ .addEqualityGroup(d1, d2)
+ .addEqualityGroup(d3)
+ .addEqualityGroup(d4)
+ .testEquals();
+ }
+
private static class FakeTicker extends Deadline.Ticker {
private long time;
diff --git a/core/src/main/java/io/grpc/internal/ClientCallImpl.java b/core/src/main/java/io/grpc/internal/ClientCallImpl.java
index af212c0..b3e431b 100644
--- a/core/src/main/java/io/grpc/internal/ClientCallImpl.java
+++ b/core/src/main/java/io/grpc/internal/ClientCallImpl.java
@@ -296,7 +296,7 @@
context.addListener(cancellationListener, directExecutor());
if (effectiveDeadline != null
// If the context has the effective deadline, we don't need to schedule an extra task.
- && context.getDeadline() != effectiveDeadline
+ && !effectiveDeadline.equals(context.getDeadline())
// If the channel has been terminated, we don't need to schedule an extra task.
&& deadlineCancellationExecutor != null) {
deadlineCancellationFuture = startDeadlineTimer(effectiveDeadline);
@@ -314,7 +314,7 @@
Deadline effectiveDeadline, @Nullable Deadline outerCallDeadline,
@Nullable Deadline callDeadline) {
if (!log.isLoggable(Level.FINE) || effectiveDeadline == null
- || outerCallDeadline != effectiveDeadline) {
+ || !effectiveDeadline.equals(outerCallDeadline)) {
return;
}