public static HashCode calculateSha256(final Blob blob) { AbstractBlob ab; if (blob instanceof AbstractBlob) { ab = ((AbstractBlob) blob); } else { ab = new AbstractBlob() { @Override public long length() { return blob.length(); } @Nonnull @Override public InputStream getNewStream() { return blob.getNewStream(); } }; } return ab.getSha256(); }
/** * To {@code Blob} instances are considered equal iff they have the * same SHA-256 hash code are equal. * @param other */ @Override public boolean equals(Object other) { if (other == this) { return true; } if (other instanceof AbstractBlob) { AbstractBlob that = (AbstractBlob) other; // optimize the comparison if both this and the other blob // already have pre-computed SHA-256 hash codes synchronized (this) { if (hashCode != null) { synchronized (that) { if (that.hashCode != null) { return hashCode.equals(that.hashCode); } } } } } return other instanceof Blob && equal(this, (Blob) other); }
/** * This hash code implementation returns the hash code of the underlying stream * @return a byte array of the hash */ protected byte[] sha256() { return getSha256().asBytes(); }
private synchronized HashCode getSha256() { // Blobs are immutable so we can safely cache the hash if (hashCode == null) { try { hashCode = supplier(this).hash(Hashing.sha256()); } catch (IOException e) { throw new IllegalStateException("Hash calculation failed", e); } } return hashCode; }
@Override public String getContentIdentity() { final String reference = getReference(); if (reference != null) { final int pos = reference.indexOf(":"); final String blobHash; if (pos > -1) { blobHash = reference.substring(0, pos); } else { blobHash = reference; } return blobHash + "#" + length(); } return super.getContentIdentity(); } };
/** * To {@code Blob} instances are considered equal iff they have the * same SHA-256 hash code are equal. * @param other */ @Override public boolean equals(Object other) { if (other == this) { return true; } if (other instanceof AbstractBlob) { AbstractBlob that = (AbstractBlob) other; // optimize the comparison if both this and the other blob // already have pre-computed SHA-256 hash codes synchronized (this) { if (hashCode != null) { synchronized (that) { if (that.hashCode != null) { return hashCode.equals(that.hashCode); } } } } } return other instanceof Blob && equal(this, (Blob) other); }
/** * This hash code implementation returns the hash code of the underlying stream * @return a byte array of the hash */ protected byte[] sha256() { return getSha256().asBytes(); }
private synchronized HashCode getSha256() { // Blobs are immutable so we can safely cache the hash if (hashCode == null) { try { hashCode = supplier(this).hash(Hashing.sha256()); } catch (IOException e) { throw new IllegalStateException("Hash calculation failed", e); } } return hashCode; }
@Override public String getContentIdentity() { final String reference = getReference(); if (reference != null) { final int pos = reference.indexOf(":"); final String blobHash; if (pos > -1) { blobHash = reference.substring(0, pos); } else { blobHash = reference; } return blobHash + "#" + length(); } return super.getContentIdentity(); } };
@Override public boolean equals(Object object) { if (Record.fastEquals(this, object)) { return true; } if (object instanceof SegmentBlob) { SegmentBlob that = (SegmentBlob) object; if (this.length() != that.length()) { return false; } List<RecordId> bulkIds = this.getBulkRecordIds(); if (bulkIds != null && bulkIds.equals(that.getBulkRecordIds())) { return true; } } return object instanceof Blob && AbstractBlob.equal(this, (Blob) object); }
public static HashCode calculateSha256(final Blob blob) { AbstractBlob ab; if (blob instanceof AbstractBlob) { ab = ((AbstractBlob) blob); } else { ab = new AbstractBlob() { @Override public long length() { return blob.length(); } @NotNull @Override public InputStream getNewStream() { return blob.getNewStream(); } }; } return ab.getSha256(); }
@Override public String toString() { return getSha256().toString(); }
public static boolean equal(Blob a, Blob b) { // shortcut: first compare lengths if known in advance long al = a.length(); long bl = b.length(); if (al != -1 && bl != -1 && al != bl) { return false; // blobs not equal, given known and non-equal lengths } String ai = a.getContentIdentity(); String bi = b.getContentIdentity(); //Check for identity first. If they are same then its //definitely same blob. If not we need to check further. if (ai != null && bi != null && ai.equals(bi)){ return true; } try { return supplier(a).contentEquals(supplier(b)); } catch (IOException e) { throw new IllegalStateException("Blob equality check failed", e); } }
@Test public void inMemoryBlob() throws Exception{ Blob b = new ArrayBasedBlob("hello world".getBytes()); String value = serializer.serialize(b); Blob b2 = serializer.deserialize(value); assertTrue(AbstractBlob.equal(b, b2)); }
@Override public String toString() { return getSha256().toString(); }
public static boolean equal(Blob a, Blob b) { // shortcut: first compare lengths if known in advance long al = a.length(); long bl = b.length(); if (al != -1 && bl != -1 && al != bl) { return false; // blobs not equal, given known and non-equal lengths } String ai = a.getContentIdentity(); String bi = b.getContentIdentity(); //Check for identity first. If they are same then its //definitely same blob. If not we need to check further. if (ai != null && bi != null && ai.equals(bi)){ return true; } try { return supplier(a).contentEquals(supplier(b)); } catch (IOException e) { throw new IllegalStateException("Blob equality check failed", e); } }
@Test public void blobs() throws Exception{ int maxInlineSize = 100; FSBlobSerializer serializer = new FSBlobSerializer(folder.getRoot(), maxInlineSize); String data = Strings.repeat("x", maxInlineSize * 10); Blob b = new ArrayBasedBlob(data.getBytes(UTF_8)); String id = serializer.serialize(b); Blob b2 = serializer.deserialize(id); assertTrue(AbstractBlob.equal(b, b2)); }
@Test public void blobComparisonBasedOnContentIdentity() throws Exception { byte[] data = bytes(100); Blob a = new TestBlob(data, "id1", false); Blob b = new TestBlob(data, "id1", false); assertTrue(AbstractBlob.equal(a, b)); Blob a2 = new TestBlob(data, "id1", true); Blob b2 = new TestBlob(data, "id2", true); assertTrue("Blobs with different id but same content should match", AbstractBlob.equal(a2, b2)); }
@Test public void blobStoreBlob() throws Exception{ Blob b = new ArrayBasedBlob("hello world".getBytes()); String value = blobStore.writeBlob(b.getNewStream()); String serValue = serializer.serialize(new BlobStoreBlob(blobStore, value)); Blob b2 = serializer.deserialize(serValue); assertTrue(AbstractBlob.equal(b, b2)); }
@Test public void blobComparisonBasedOnLength() throws Exception { Blob a = new TestBlob(bytes(100), null, false); Blob b = new TestBlob(bytes(50), null, false); assertFalse("Blob comparison should not fallback on content if lengths not same", AbstractBlob.equal(a, b)); }