RangeRequest Breaches The hashCode() Contract
jeremyk-91 opened this issue · comments
@Test
public void wat() {
RangeRequest r1 = RangeRequest.builder()
.startRowInclusive(PtBytes.toBytes("tom"))
.endRowExclusive(PtBytes.toBytes("zzzz"))
.retainColumns(ImmutableList.of(PtBytes.toBytes("name")))
.build();
RangeRequest r2 = RangeRequest.builder()
.startRowInclusive(PtBytes.toBytes("tom"))
.endRowExclusive(PtBytes.toBytes("zzzz"))
.retainColumns(ImmutableList.of(PtBytes.toBytes("name")))
.build();
assertThat(r1).isEqualTo(r2); // passes
assertThat(r1.hashCode()).isEqualTo(r2.hashCode()); // :(
assertThat(ImmutableSet.of(r1, r2).size()).isEqualTo(1); // :(
}
Ran into this when trying to work on the range requests issue. Looks like this is caused by the way the hash calls Object.hash
on an ImmutableSortedSet of byte arrays, among other things - this extracts the hash code of the ImmutableSortedSet, which is based on the hash code of its elements (but of course for arrays these are identity-hashcodes).
This is not a problem for Guava, because they do warn about undefined behaviour for users of arrays with a comparator like unsigned bytes.
Unsure about the scope of the badness, but uses of things like Map<RangeRequest, T> where we expect multiple updates to a key to replace its value / use computeIfAbsent style workflows are broken.