@Override boolean equalsSameBits(HashCode that) { // We don't use MessageDigest.isEqual() here because its contract does not guarantee // constant-time evaluation (no short-circuiting). if (this.bytes.length != that.getBytesInternal().length) { return false; } boolean areEqual = true; for (int i = 0; i < this.bytes.length; i++) { areEqual &= (this.bytes[i] == that.getBytesInternal()[i]); } return areEqual; }
@Override boolean equalsSameBits(HashCode that) { // We don't use MessageDigest.isEqual() here because its contract does not guarantee // constant-time evaluation (no short-circuiting). if (this.bytes.length != that.getBytesInternal().length) { return false; } boolean areEqual = true; for (int i = 0; i < this.bytes.length; i++) { areEqual &= (this.bytes[i] == that.getBytesInternal()[i]); } return areEqual; }
@Override boolean equalsSameBits(HashCode that) { // We don't use MessageDigest.isEqual() here because its contract does not guarantee // constant-time evaluation (no short-circuiting). if (this.bytes.length != that.getBytesInternal().length) { return false; } boolean areEqual = true; for (int i = 0; i < this.bytes.length; i++) { areEqual &= (this.bytes[i] == that.getBytesInternal()[i]); } return areEqual; }
/** * Returns a string containing each byte of {@link #asBytes}, in order, as a two-digit unsigned * hexadecimal number in lower case. * * <p>Note that if the output is considered to be a single hexadecimal number, this hash code's * bytes are the <i>big-endian</i> representation of that number. This may be surprising since * everything else in the hashing API uniformly treats multibyte values as little-endian. But this * format conveniently matches that of utilities such as the UNIX {@code md5sum} command. * * <p>To create a {@code HashCode} from its string representation, see {@link #fromString}. */ @Override public final String toString() { byte[] bytes = getBytesInternal(); StringBuilder sb = new StringBuilder(2 * bytes.length); for (byte b : bytes) { sb.append(hexDigits[(b >> 4) & 0xf]).append(hexDigits[b & 0xf]); } return sb.toString(); }
/** * Returns a string containing each byte of {@link #asBytes}, in order, as a two-digit unsigned * hexadecimal number in lower case. * * <p>Note that if the output is considered to be a single hexadecimal number, this hash code's * bytes are the <i>big-endian</i> representation of that number. This may be surprising since * everything else in the hashing API uniformly treats multibyte values as little-endian. But this * format conveniently matches that of utilities such as the UNIX {@code md5sum} command. * * <p>To create a {@code HashCode} from its string representation, see {@link #fromString}. */ @Override public final String toString() { byte[] bytes = getBytesInternal(); StringBuilder sb = new StringBuilder(2 * bytes.length); for (byte b : bytes) { sb.append(hexDigits[(b >> 4) & 0xf]).append(hexDigits[b & 0xf]); } return sb.toString(); }
/** * Returns a string containing each byte of {@link #asBytes}, in order, as a two-digit unsigned * hexadecimal number in lower case. * * <p>Note that if the output is considered to be a single hexadecimal number, this hash code's * bytes are the <i>big-endian</i> representation of that number. This may be surprising since * everything else in the hashing API uniformly treats multibyte values as little-endian. But this * format conveniently matches that of utilities such as the UNIX {@code md5sum} command. * * <p>To create a {@code HashCode} from its string representation, see {@link #fromString}. */ @Override public final String toString() { byte[] bytes = getBytesInternal(); StringBuilder sb = new StringBuilder(2 * bytes.length); for (byte b : bytes) { sb.append(hexDigits[(b >> 4) & 0xf]).append(hexDigits[b & 0xf]); } return sb.toString(); }
/** * Returns a "Java hash code" for this {@code HashCode} instance; this is well-defined (so, for * example, you can safely put {@code HashCode} instances into a {@code HashSet}) but is otherwise * probably not what you want to use. */ @Override public final int hashCode() { // If we have at least 4 bytes (32 bits), just take the first 4 bytes. Since this is // already a (presumably) high-quality hash code, any four bytes of it will do. if (bits() >= 32) { return asInt(); } // If we have less than 4 bytes, use them all. byte[] bytes = getBytesInternal(); int val = (bytes[0] & 0xFF); for (int i = 1; i < bytes.length; i++) { val |= ((bytes[i] & 0xFF) << (i * 8)); } return val; }
/** * Returns a "Java hash code" for this {@code HashCode} instance; this is well-defined (so, for * example, you can safely put {@code HashCode} instances into a {@code HashSet}) but is otherwise * probably not what you want to use. */ @Override public final int hashCode() { // If we have at least 4 bytes (32 bits), just take the first 4 bytes. Since this is // already a (presumably) high-quality hash code, any four bytes of it will do. if (bits() >= 32) { return asInt(); } // If we have less than 4 bytes, use them all. byte[] bytes = getBytesInternal(); int val = (bytes[0] & 0xFF); for (int i = 1; i < bytes.length; i++) { val |= ((bytes[i] & 0xFF) << (i * 8)); } return val; }
/** * Returns a "Java hash code" for this {@code HashCode} instance; this is well-defined (so, for * example, you can safely put {@code HashCode} instances into a {@code HashSet}) but is otherwise * probably not what you want to use. */ @Override public final int hashCode() { // If we have at least 4 bytes (32 bits), just take the first 4 bytes. Since this is // already a (presumably) high-quality hash code, any four bytes of it will do. if (bits() >= 32) { return asInt(); } // If we have less than 4 bytes, use them all. byte[] bytes = getBytesInternal(); int val = (bytes[0] & 0xFF); for (int i = 1; i < bytes.length; i++) { val |= ((bytes[i] & 0xFF) << (i * 8)); } return val; }
@Override public <T> boolean mightContain( T object, Funnel<? super T> funnel, int numHashFunctions, LockFreeBitArray bits) { long bitSize = bits.bitSize(); byte[] bytes = Hashing.murmur3_128().hashObject(object, funnel).getBytesInternal(); long hash1 = lowerEight(bytes); long hash2 = upperEight(bytes); long combinedHash = hash1; for (int i = 0; i < numHashFunctions; i++) { // Make the combined hash positive and indexable if (!bits.get((combinedHash & Long.MAX_VALUE) % bitSize)) { return false; } combinedHash += hash2; } return true; }
@Override public <T> boolean put( T object, Funnel<? super T> funnel, int numHashFunctions, LockFreeBitArray bits) { long bitSize = bits.bitSize(); byte[] bytes = Hashing.murmur3_128().hashObject(object, funnel).getBytesInternal(); long hash1 = lowerEight(bytes); long hash2 = upperEight(bytes); boolean bitsChanged = false; long combinedHash = hash1; for (int i = 0; i < numHashFunctions; i++) { // Make the combined hash positive and indexable bitsChanged |= bits.set((combinedHash & Long.MAX_VALUE) % bitSize); combinedHash += hash2; } return bitsChanged; }
public void testGetBytesInternal_noCloneOccurs() { byte[] bytes = new byte[] {(byte) 0xcd, (byte) 0xab, (byte) 0x00, (byte) 0x00}; HashCode hashCode = HashCode.fromBytes(bytes); assertEquals(0x0000abcd, hashCode.asInt()); assertEquals("cdab0000", hashCode.toString()); hashCode.getBytesInternal()[0] = (byte) 0x00; assertEquals(0x0000ab00, hashCode.asInt()); assertEquals("00ab0000", hashCode.toString()); }
@Override public <T> boolean put( T object, Funnel<? super T> funnel, int numHashFunctions, LockFreeBitArray bits) { long bitSize = bits.bitSize(); byte[] bytes = Hashing.murmur3_128().hashObject(object, funnel).getBytesInternal(); long hash1 = lowerEight(bytes); long hash2 = upperEight(bytes); boolean bitsChanged = false; long combinedHash = hash1; for (int i = 0; i < numHashFunctions; i++) { // Make the combined hash positive and indexable bitsChanged |= bits.set((combinedHash & Long.MAX_VALUE) % bitSize); combinedHash += hash2; } return bitsChanged; }
@Override public <T> boolean mightContain( T object, Funnel<? super T> funnel, int numHashFunctions, LockFreeBitArray bits) { long bitSize = bits.bitSize(); byte[] bytes = Hashing.murmur3_128().hashObject(object, funnel).getBytesInternal(); long hash1 = lowerEight(bytes); long hash2 = upperEight(bytes); long combinedHash = hash1; for (int i = 0; i < numHashFunctions; i++) { // Make the combined hash positive and indexable if (!bits.get((combinedHash & Long.MAX_VALUE) % bitSize)) { return false; } combinedHash += hash2; } return true; }
@Override public <T> boolean put( T object, Funnel<? super T> funnel, int numHashFunctions, LockFreeBitArray bits) { long bitSize = bits.bitSize(); byte[] bytes = Hashing.murmur3_128().hashObject(object, funnel).getBytesInternal(); long hash1 = lowerEight(bytes); long hash2 = upperEight(bytes); boolean bitsChanged = false; long combinedHash = hash1; for (int i = 0; i < numHashFunctions; i++) { // Make the combined hash positive and indexable bitsChanged |= bits.set((combinedHash & Long.MAX_VALUE) % bitSize); combinedHash += hash2; } return bitsChanged; }
@Override public <T> boolean mightContain( T object, Funnel<? super T> funnel, int numHashFunctions, LockFreeBitArray bits) { long bitSize = bits.bitSize(); byte[] bytes = Hashing.murmur3_128().hashObject(object, funnel).getBytesInternal(); long hash1 = lowerEight(bytes); long hash2 = upperEight(bytes); long combinedHash = hash1; for (int i = 0; i < numHashFunctions; i++) { // Make the combined hash positive and indexable if (!bits.get((combinedHash & Long.MAX_VALUE) % bitSize)) { return false; } combinedHash += hash2; } return true; }
@Override boolean equalsSameBits(HashCode that) { // We don't use MessageDigest.isEqual() here because its contract does not guarantee // constant-time evaluation (no short-circuiting). if (this.bytes.length != that.getBytesInternal().length) { return false; } boolean areEqual = true; for (int i = 0; i < this.bytes.length; i++) { areEqual &= (this.bytes[i] == that.getBytesInternal()[i]); } return areEqual; }
@Override boolean equalsSameBits(HashCode that) { // We don't use MessageDigest.isEqual() here because its contract does not guarantee // constant-time evaluation (no short-circuiting). if (this.bytes.length != that.getBytesInternal().length) { return false; } boolean areEqual = true; for (int i = 0; i < this.bytes.length; i++) { areEqual &= (this.bytes[i] == that.getBytesInternal()[i]); } return areEqual; }
@Override public <T> boolean put( T object, Funnel<? super T> funnel, int numHashFunctions, LockFreeBitArray bits) { long bitSize = bits.bitSize(); byte[] bytes = Hashing.murmur3_128().hashObject(object, funnel).getBytesInternal(); long hash1 = lowerEight(bytes); long hash2 = upperEight(bytes); boolean bitsChanged = false; long combinedHash = hash1; for (int i = 0; i < numHashFunctions; i++) { // Make the combined hash positive and indexable bitsChanged |= bits.set((combinedHash & Long.MAX_VALUE) % bitSize); combinedHash += hash2; } return bitsChanged; }
public void testGetBytesInternal_noCloneOccurs() { byte[] bytes = new byte[] { (byte) 0xcd, (byte) 0xab, (byte) 0x00, (byte) 0x00 }; HashCode hashCode = HashCode.fromBytes(bytes); assertEquals(0x0000abcd, hashCode.asInt()); assertEquals("cdab0000", hashCode.toString()); hashCode.getBytesInternal()[0] = (byte) 0x00; assertEquals(0x0000ab00, hashCode.asInt()); assertEquals("00ab0000", hashCode.toString()); }