diff --git a/common/src/main/java/io/netty/util/internal/MathUtil.java b/common/src/main/java/io/netty/util/internal/MathUtil.java index 632b0d3515..e6a042c408 100644 --- a/common/src/main/java/io/netty/util/internal/MathUtil.java +++ b/common/src/main/java/io/netty/util/internal/MathUtil.java @@ -64,6 +64,20 @@ public final class MathUtil { return (index | length | (index + length) | (capacity - (index + length))) < 0; } + /** + * Compares two {@code int} values. + * + * @param x the first {@code int} to compare + * @param y the second {@code int} to compare + * @return the value {@code 0} if {@code x == y}; + * {@code -1} if {@code x < y}; and + * {@code 1} if {@code x > y} + */ + public static int compare(final int x, final int y) { + // do not subtract for comparison, it could overflow + return x < y ? -1 : (x > y ? 1 : 0); + } + /** * Compare two {@code long} values. * @param x the first {@code long} to compare. diff --git a/transport/src/main/java/io/netty/channel/DefaultChannelId.java b/transport/src/main/java/io/netty/channel/DefaultChannelId.java index 1409bcbadd..cca96b91a9 100644 --- a/transport/src/main/java/io/netty/channel/DefaultChannelId.java +++ b/transport/src/main/java/io/netty/channel/DefaultChannelId.java @@ -178,10 +178,10 @@ public final class DefaultChannelId implements ChannelId { // random int random = ThreadLocalRandom.current().nextInt(); - hashCode = random; i = writeInt(i, random); - assert i == data.length; + + hashCode = Arrays.hashCode(data); } private int writeInt(int i, int value) { @@ -247,21 +247,35 @@ public final class DefaultChannelId implements ChannelId { } @Override - public int compareTo(ChannelId o) { - return 0; + public int compareTo(final ChannelId o) { + if (o instanceof DefaultChannelId) { + final byte[] otherData = ((DefaultChannelId)o).data; + if (this == o) { + // short circuit + return 0; + } + // lexicographic comparison + int len1 = data.length; + int len2 = otherData.length; + int len = Math.min(len1, len2); + + for (int k = 0; k < len; k++) { + byte x = data[k]; + byte y = otherData[k]; + if (x != y) { + // treat these as unsigned bytes for comparison + return (x & 0xff) - (y & 0xff); + } + } + return len1 - len2; + } + + return asLongText().compareTo(o.asLongText()); } @Override public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (!(obj instanceof DefaultChannelId)) { - return false; - } - - return Arrays.equals(data, ((DefaultChannelId) obj).data); + return this == obj || (obj instanceof DefaultChannelId && Arrays.equals(data, ((DefaultChannelId) obj).data)); } @Override diff --git a/transport/src/main/java/io/netty/channel/embedded/EmbeddedChannelId.java b/transport/src/main/java/io/netty/channel/embedded/EmbeddedChannelId.java index 0bf0b25d45..7bd13ec4ed 100644 --- a/transport/src/main/java/io/netty/channel/embedded/EmbeddedChannelId.java +++ b/transport/src/main/java/io/netty/channel/embedded/EmbeddedChannelId.java @@ -40,7 +40,7 @@ final class EmbeddedChannelId implements ChannelId { } @Override - public int compareTo(ChannelId o) { + public int compareTo(final ChannelId o) { if (o instanceof EmbeddedChannelId) { return 0; } diff --git a/transport/src/test/java/io/netty/channel/embedded/CustomChannelId.java b/transport/src/test/java/io/netty/channel/embedded/CustomChannelId.java index 397df1a76e..8d42f29ea0 100644 --- a/transport/src/test/java/io/netty/channel/embedded/CustomChannelId.java +++ b/transport/src/test/java/io/netty/channel/embedded/CustomChannelId.java @@ -16,22 +16,25 @@ package io.netty.channel.embedded; import io.netty.channel.ChannelId; +import io.netty.util.internal.MathUtil; public class CustomChannelId implements ChannelId { + private static final long serialVersionUID = 1L; private int id; - public CustomChannelId(int id) { + CustomChannelId(int id) { this.id = id; } @Override - public int compareTo(ChannelId o) { + public int compareTo(final ChannelId o) { if (o instanceof CustomChannelId) { - return id - ((CustomChannelId) o).id; + return MathUtil.compare(id, ((CustomChannelId)o).id); } - return -1; + + return asLongText().compareTo(o.asLongText()); } @Override @@ -41,10 +44,7 @@ public class CustomChannelId implements ChannelId { @Override public boolean equals(Object obj) { - if (obj instanceof CustomChannelId) { - return id == ((CustomChannelId) obj).id; - } - return false; + return obj instanceof CustomChannelId && id == ((CustomChannelId) obj).id; } @Override