Index: src/main/java/org/apache/jackrabbit/oak/plugins/memory/AbstractBlob.java
===================================================================
--- src/main/java/org/apache/jackrabbit/oak/plugins/memory/AbstractBlob.java	(revision 1565599)
+++ src/main/java/org/apache/jackrabbit/oak/plugins/memory/AbstractBlob.java	(working copy)
@@ -47,6 +47,10 @@
     }
 
     public static boolean equal(Blob a, Blob b) {
+        // shortcut: first compare lengths if known in advance
+        if (a.length() != -1 && b.length() != -1 && a.length() != b.length()) {
+            return false;
+        }
         try {
             return ByteStreams.equal(supplier(a), supplier(b));
         } catch (IOException e) {
Index: src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
===================================================================
--- src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java	(revision 1565599)
+++ src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java	(working copy)
@@ -50,6 +50,8 @@
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.UUID;
+import java.util.zip.CheckedInputStream;
+import java.util.zip.Checksum;
 
 import javax.jcr.PropertyType;
 
@@ -64,6 +66,7 @@
 import com.google.common.base.Charsets;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import com.google.common.hash.Hasher;
 import com.google.common.io.ByteStreams;
 import com.google.common.io.Closeables;
 
@@ -691,17 +694,42 @@
      * @throws IOException if the stream could not be read
      */
     public SegmentBlob writeStream(InputStream stream) throws IOException {
+        long checksum = -1;
         RecordId id = SegmentStream.getRecordIdIfAvailable(stream, store);
         if (id == null) {
             boolean threw = true;
             try {
-                id = internalWriteStream(stream);
+                final Hasher hasher = SegmentBlob.newHashFunction().newHasher();
+                CheckedInputStream cis = new CheckedInputStream(stream,
+                        new Checksum() {
+                            @Override
+                            public void update(byte[] b, int off, int len) {
+                                hasher.putBytes(b, off, len);
+                            }
+
+                            @Override
+                            public void update(int b) {
+                                hasher.putByte((byte) b);
+                            }
+
+                            @Override
+                            public void reset() {
+                                throw new UnsupportedOperationException();
+                            }
+
+                            @Override
+                            public long getValue() {
+                                throw new UnsupportedOperationException();
+                            }
+                        });
+                id = internalWriteStream(cis);
+                checksum = hasher.hash().padToLong();
                 threw = false;
             } finally {
                 Closeables.close(stream, threw);
             }
         }
-        return new SegmentBlob(dummySegment, id);
+        return new SegmentBlob(dummySegment, id, checksum);
     }
 
     private RecordId internalWriteStream(InputStream stream)
Index: src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentBlob.java
===================================================================
--- src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentBlob.java	(revision 1565599)
+++ src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentBlob.java	(working copy)
@@ -27,6 +27,12 @@
 import org.apache.jackrabbit.oak.api.Blob;
 import org.apache.jackrabbit.oak.plugins.memory.AbstractBlob;
 
+import com.google.common.hash.HashFunction;
+import com.google.common.hash.Hashing;
+import com.google.common.io.ByteStreams;
+import com.google.common.io.InputSupplier;
+
+import java.io.IOException;
 import java.io.InputStream;
 
 class SegmentBlob extends Record implements Blob {
@@ -35,6 +41,11 @@
         super(segment, id);
     }
 
+    SegmentBlob(Segment segment, RecordId id, long checksum) {
+        super(segment, id);
+        this.checksum = checksum;
+    }
+
     private InputStream getInlineStream(
             Segment segment, int offset, int length) {
         byte[] inline = new byte[length];
@@ -114,14 +125,51 @@
 
     //------------------------------------------------------------< Object >--
 
+    long checksum = -1;
+
+    private synchronized long getChecksum() {
+        if (checksum == -1) {
+            checksum = buildHash();
+        }
+        return checksum;
+    }
+
+    public static HashFunction newHashFunction() {
+        return Hashing.adler32();
+    }
+
+    private long buildHash() {
+        try {
+            return ByteStreams.hash(supplier(this), newHashFunction())
+                    .padToLong();
+        } catch (IOException e) {
+            throw new IllegalStateException("Hash calculation failed", e);
+        }
+    }
+
+    private static InputSupplier<InputStream> supplier(final Blob blob) {
+        return new InputSupplier<InputStream>() {
+            @Override
+            public InputStream getInput() throws IOException {
+                return blob.getNewStream();
+            }
+        };
+    }
+
     @Override
     public boolean equals(Object object) {
         if (object == this || fastEquals(this, object)) {
             return true;
-        } else {
-            return object instanceof Blob
-                    && AbstractBlob.equal(this, (Blob) object);
+        } 
+        if (object instanceof SegmentBlob) {
+            SegmentBlob other = (SegmentBlob) object;
+            if (length() != other.length()) {
+                return false;
+            }
+            return getChecksum() == other.getChecksum();
         }
+        return object instanceof Blob
+                && AbstractBlob.equal(this, (Blob) object);
     }
 
     @Override
