Browse Source

Merge -r 1335196:1335197 from trunk to branch-0.23. Fixes: MAPREDUCE-4226

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-0.23@1335199 13f79535-47bb-0310-9956-ffa450edef68
Thomas White 13 years ago
parent
commit
9f2c5fb74e

+ 3 - 0
hadoop-mapreduce-project/CHANGES.txt

@@ -177,6 +177,9 @@ Release 0.23.3 - UNRELEASED
     MAPREDUCE-4220. RM apps page starttime/endtime sorts are incorrect
     (Jonathan Eagles via bobby)
 
+    MAPREDUCE-4226. ConcurrentModificationException in FileSystemCounterGroup.
+    (tomwhite)
+
 Release 0.23.2 - UNRELEASED
 
   INCOMPATIBLE CHANGES

+ 3 - 1
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/counters/FileSystemCounterGroup.java

@@ -23,6 +23,7 @@ import java.io.DataOutput;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentSkipListMap;
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
@@ -54,7 +55,8 @@ public abstract class FileSystemCounterGroup<C extends Counter>
 
   // C[] would need Array.newInstance which requires a Class<C> reference.
   // Just a few local casts probably worth not having to carry it around.
-  private final Map<String, Object[]> map = Maps.newTreeMap();
+  private final Map<String, Object[]> map =
+    new ConcurrentSkipListMap<String, Object[]>();
   private String displayName;
 
   private static final Joiner NAME_JOINER = Joiner.on('_');

+ 20 - 0
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/test/java/org/apache/hadoop/mapred/TestCounters.java

@@ -18,6 +18,7 @@
 package org.apache.hadoop.mapred;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
 import java.text.ParseException;
@@ -203,6 +204,25 @@ public class TestCounters {
     counters.incrCounter("group1", "counter2", 1);
     iterator.next();
   }
+
+  @Test
+  public void testFileSystemGroupIteratorConcurrency() {
+    Counters counters = new Counters();
+    // create 2 filesystem counter groups
+    counters.findCounter("fs1", FileSystemCounter.BYTES_READ).increment(1);
+    counters.findCounter("fs2", FileSystemCounter.BYTES_READ).increment(1);
+    
+    // Iterate over the counters in this group while updating counters in
+    // the group
+    Group group = counters.getGroup(FileSystemCounter.class.getName());
+    Iterator<Counter> iterator = group.iterator();
+    counters.findCounter("fs3", FileSystemCounter.BYTES_READ).increment(1);
+    assertTrue(iterator.hasNext());
+    iterator.next();
+    counters.findCounter("fs3", FileSystemCounter.BYTES_READ).increment(1);
+    assertTrue(iterator.hasNext());
+    iterator.next();
+  }
   
   public static void main(String[] args) throws IOException {
     new TestCounters().testCounters();