Memoize Tuple hashes and do not pack for equality check

This commit is contained in:
Alec Grieser 2019-02-17 10:40:38 -08:00
parent c6947db091
commit 9bf4940249
No known key found for this signature in database
GPG Key ID: CAF63551C60D3462
2 changed files with 21 additions and 4 deletions

View File

@ -228,7 +228,7 @@ public class Subspace {
if(!contains(key))
throw new IllegalArgumentException("Cannot unpack key that is not contained in subspace.");
return Tuple.fromBytes(Arrays.copyOfRange(key, rawPrefix.length, key.length));
return Tuple.fromBytes(key, rawPrefix.length, key.length - rawPrefix.length);
}
/**

View File

@ -71,6 +71,7 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
private static IterableComparator comparator = new IterableComparator();
private List<Object> elements;
private int memoizedHash = 0;
private Tuple(List<? extends Object> elements, Object newItem) {
this(elements);
@ -759,14 +760,28 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
}
/**
* Returns a hash code value for this {@code Tuple}.
* Returns a hash code value for this {@code Tuple}. Computing the hash code is fairly expensive
* as it involves packing the underlying {@code Tuple} to bytes. However, this value is memoized,
* so for any given {@code Tuple}, it only needs to be computed once. This means that it is
* generally safe to use {@code Tuple}s with hash-based data structures such as
* {@link java.util.HashSet HashSet}s or {@link java.util.HashMap HashMap}s.
* {@inheritDoc}
*
* @return a hash code for this {@code Tuple} that can be used by hash tables
*/
@Override
public int hashCode() {
return Arrays.hashCode(this.pack());
if(memoizedHash == 0) {
byte[] packed;
if(hasIncompleteVersionstamp()) {
packed = packWithVersionstamp(null);
}
else {
packed = pack();
}
memoizedHash = Arrays.hashCode(packed);
}
return memoizedHash;
}
/**
@ -781,8 +796,10 @@ public class Tuple implements Comparable<Tuple>, Iterable<Object> {
public boolean equals(Object o) {
if(o == null)
return false;
if(o == this)
return true;
if(o instanceof Tuple) {
return Arrays.equals(this.pack(), ((Tuple) o).pack());
return compareTo((Tuple)o) == 0;
}
return false;
}