diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index 95de3d3ab3..89bd85cd07 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -415,6 +415,9 @@ Branch-2 ( Unreleased changes ) HDFS-3697. Enable fadvise readahead by default. (todd) + HDFS-2421. Improve the concurrency of SerialNumberMap in NameNode. + (Jing Zhao and Weiyan Wang via szetszwo) + BUG FIXES HDFS-3385. The last block of INodeFileUnderConstruction is not diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/SerialNumberManager.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/SerialNumberManager.java index 9a7118444d..e12ce698f3 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/SerialNumberManager.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/SerialNumberManager.java @@ -17,7 +17,10 @@ */ package org.apache.hadoop.hdfs.server.namenode; -import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; + /** Manage name-to-serial-number maps for users and groups. */ class SerialNumberManager { @@ -40,33 +43,41 @@ private SerialNumberManager() {} } private static class SerialNumberMap { - private int max = 0; - private int nextSerialNumber() {return max++;} + private AtomicInteger max = new AtomicInteger(1); + private ConcurrentMap t2i = new ConcurrentHashMap(); + private ConcurrentMap i2t = new ConcurrentHashMap(); - private Map t2i = new HashMap(); - private Map i2t = new HashMap(); - - synchronized int get(T t) { + int get(T t) { + if (t == null) { + return 0; + } Integer sn = t2i.get(t); if (sn == null) { - sn = nextSerialNumber(); - t2i.put(t, sn); + sn = max.getAndIncrement(); + Integer old = t2i.putIfAbsent(t, sn); + if (old != null) { + return old; + } i2t.put(sn, t); } return sn; } - synchronized T get(int i) { - if (!i2t.containsKey(i)) { + T get(int i) { + if (i == 0) { + return null; + } + T t = i2t.get(i); + if (t == null) { throw new IllegalStateException("!i2t.containsKey(" + i + "), this=" + this); } - return i2t.get(i); + return t; } - @Override + /** {@inheritDoc} */ public String toString() { return "max=" + max + ",\n t2i=" + t2i + ",\n i2t=" + i2t; } } -} +} \ No newline at end of file