You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by om...@apache.org on 2008/06/30 19:18:16 UTC

svn commit: r672823 - in /hadoop/core/trunk: CHANGES.txt src/core/org/apache/hadoop/io/MD5Hash.java src/test/org/apache/hadoop/io/TestMD5Hash.java

Author: omalley
Date: Mon Jun 30 10:18:16 2008
New Revision: 672823

URL: http://svn.apache.org/viewvc?rev=672823&view=rev
Log:
HADOOP-3556. Removed lock contention in MD5Hash by changing the 
singleton MessageDigester by an instance per Thread using 
ThreadLocal. Contributed by Iv‡n de Prado.

Modified:
    hadoop/core/trunk/CHANGES.txt
    hadoop/core/trunk/src/core/org/apache/hadoop/io/MD5Hash.java
    hadoop/core/trunk/src/test/org/apache/hadoop/io/TestMD5Hash.java

Modified: hadoop/core/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/core/trunk/CHANGES.txt?rev=672823&r1=672822&r2=672823&view=diff
==============================================================================
--- hadoop/core/trunk/CHANGES.txt (original)
+++ hadoop/core/trunk/CHANGES.txt Mon Jun 30 10:18:16 2008
@@ -30,6 +30,7 @@
     All of them default to "\t". (Zheng Shao via omalley)
 
   IMPROVEMENTS
+
     HADOOP-3577. Tools to inject blocks into name node and simulated
     data nodes for testing. (Sanjay Radia via hairong)
 
@@ -38,6 +39,10 @@
 
   OPTIMIZATIONS
 
+    HADOOP-3556. Removed lock contention in MD5Hash by changing the 
+    singleton MessageDigester by an instance per Thread using 
+    ThreadLocal. (Iv‡n de Prado via omalley)
+
   BUG FIXES
 
     HADOOP-3563.  Refactor the distributed upgrade code so that it is 

Modified: hadoop/core/trunk/src/core/org/apache/hadoop/io/MD5Hash.java
URL: http://svn.apache.org/viewvc/hadoop/core/trunk/src/core/org/apache/hadoop/io/MD5Hash.java?rev=672823&r1=672822&r2=672823&view=diff
==============================================================================
--- hadoop/core/trunk/src/core/org/apache/hadoop/io/MD5Hash.java (original)
+++ hadoop/core/trunk/src/core/org/apache/hadoop/io/MD5Hash.java Mon Jun 30 10:18:16 2008
@@ -28,14 +28,15 @@
  */
 public class MD5Hash implements WritableComparable {
   public static final int MD5_LEN = 16;
-  private static final MessageDigest DIGESTER;
-  static {
-    try {
-      DIGESTER = MessageDigest.getInstance("MD5");
-    } catch (NoSuchAlgorithmException e) {
-      throw new RuntimeException(e);
+  private static ThreadLocal<MessageDigest> DIGESTER_FACTORY = new ThreadLocal<MessageDigest>() {
+    protected MessageDigest initialValue() {
+      try {
+        return MessageDigest.getInstance("MD5");
+      } catch (NoSuchAlgorithmException e) {
+        throw new RuntimeException(e);
+      }
     }
-  }
+  };
 
   private byte[] digest;
 
@@ -89,10 +90,9 @@
   /** Construct a hash value for a byte array. */
   public static MD5Hash digest(byte[] data, int start, int len) {
     byte[] digest;
-    synchronized (DIGESTER) {
-      DIGESTER.update(data, start, len);
-      digest = DIGESTER.digest();
-    }
+    MessageDigest digester = DIGESTER_FACTORY.get();
+    digester.update(data, start, len);
+    digest = digester.digest();
     return new MD5Hash(digest);
   }
 

Modified: hadoop/core/trunk/src/test/org/apache/hadoop/io/TestMD5Hash.java
URL: http://svn.apache.org/viewvc/hadoop/core/trunk/src/test/org/apache/hadoop/io/TestMD5Hash.java?rev=672823&r1=672822&r2=672823&view=diff
==============================================================================
--- hadoop/core/trunk/src/test/org/apache/hadoop/io/TestMD5Hash.java (original)
+++ hadoop/core/trunk/src/test/org/apache/hadoop/io/TestMD5Hash.java Mon Jun 30 10:18:16 2008
@@ -37,15 +37,17 @@
     return new MD5Hash(digest.digest());
   }
 
+  protected static byte[] D00 = new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+  protected static byte[] DFF = new byte[] {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; 
+  
   public void testMD5Hash() throws Exception {
     MD5Hash md5Hash = getTestHash();
 
-    MD5Hash md5Hash00
-      = new MD5Hash(new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
+    final MD5Hash md5Hash00
+      = new MD5Hash(D00);
 
-    MD5Hash md5HashFF
-      = new MD5Hash(new byte[] {-1, -1, -1, -1, -1, -1, -1, -1,
-                                -1, -1, -1, -1, -1, -1, -1, -1});
+    final MD5Hash md5HashFF
+      = new MD5Hash(DFF);
     
     MD5Hash orderedHash = new MD5Hash(new byte[]{1,2,3,4,5,6,7,8,9,10,11,12,
                                                  13,14,15,16});
@@ -84,6 +86,30 @@
     assertEquals(0xfffefdfcfbfaf9f8L, backwardHash.halfDigest());
     assertTrue("hash collision", 
                closeHash1.hashCode() != closeHash2.hashCode());
+     
+    Thread t1 = new Thread() {      
+      public void run() {
+        for (int i = 0; i < 100; i++) {
+          MD5Hash hash = new MD5Hash(DFF);
+          assertEquals(hash, md5HashFF);
+        }        
+      }
+    };
+    
+    Thread t2 = new Thread() {
+      public void run() {
+        for (int i = 0; i < 100; i++) {
+          MD5Hash hash = new MD5Hash(D00);
+          assertEquals(hash, md5Hash00);
+        }
+      }      
+    };
+    
+    t1.start();
+    t2.start();
+    t1.join();
+    t2.join();
+    
   }
 	
 }