Support keyLock in LockGroup (#38)

Change-Id: I43360da8b4c701bf02d635a7270af96a433ca5c7
diff --git a/pom.xml b/pom.xml
index 2e8d352..8c8fc7d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
 
     <groupId>com.baidu.hugegraph</groupId>
     <artifactId>hugegraph-common</artifactId>
-    <version>1.6.14</version>
+    <version>1.6.15</version>
 
     <name>hugegraph-common</name>
     <url>https://github.com/hugegraph/hugegraph-common</url>
@@ -218,7 +218,7 @@
                         <manifestEntries>
                             <!-- Must be on one line, otherwise the automatic
                                  upgrade script cannot replace the version number -->
-                            <Implementation-Version>1.6.14.0</Implementation-Version>
+                            <Implementation-Version>1.6.15.0</Implementation-Version>
                         </manifestEntries>
                     </archive>
                 </configuration>
diff --git a/src/main/java/com/baidu/hugegraph/concurrent/LockGroup.java b/src/main/java/com/baidu/hugegraph/concurrent/LockGroup.java
index b5172fe..44d064d 100644
--- a/src/main/java/com/baidu/hugegraph/concurrent/LockGroup.java
+++ b/src/main/java/com/baidu/hugegraph/concurrent/LockGroup.java
@@ -57,6 +57,13 @@
         return (ReadWriteLock) this.locksMap.get(lockName);
     }
 
+    public KeyLock keyLock(String lockName) {
+        if (!this.locksMap.containsKey(lockName)) {
+            this.locksMap.putIfAbsent(lockName, new KeyLock());
+        }
+        return (KeyLock) this.locksMap.get(lockName);
+    }
+
     public String name() {
         return this.name;
     }
diff --git a/src/main/java/com/baidu/hugegraph/version/CommonVersion.java b/src/main/java/com/baidu/hugegraph/version/CommonVersion.java
index 92c5f27..74498bc 100644
--- a/src/main/java/com/baidu/hugegraph/version/CommonVersion.java
+++ b/src/main/java/com/baidu/hugegraph/version/CommonVersion.java
@@ -27,5 +27,5 @@
 
     // The second parameter of Version.of() is for all-in-one JAR
     public static final Version VERSION = Version.of(CommonVersion.class,
-                                                     "1.6.14");
+                                                     "1.6.15");
 }
diff --git a/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java b/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java
index 6131b33..ef3f194 100644
--- a/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java
+++ b/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java
@@ -24,6 +24,7 @@
 
 import com.baidu.hugegraph.testutil.AssertTest;
 import com.baidu.hugegraph.testutil.WhiteboxTest;
+import com.baidu.hugegraph.unit.concurrent.LockGroupTest;
 import com.baidu.hugegraph.unit.config.HugeConfigTest;
 import com.baidu.hugegraph.unit.date.SafeDateFormatTest;
 import com.baidu.hugegraph.unit.event.EventHubTest;
@@ -55,6 +56,7 @@
 
 @RunWith(Suite.class)
 @Suite.SuiteClasses({
+    LockGroupTest.class,
     HugeConfigTest.class,
     SafeDateFormatTest.class,
     EventHubTest.class,
diff --git a/src/test/java/com/baidu/hugegraph/unit/concurrent/LockGroupTest.java b/src/test/java/com/baidu/hugegraph/unit/concurrent/LockGroupTest.java
new file mode 100644
index 0000000..bd830fe
--- /dev/null
+++ b/src/test/java/com/baidu/hugegraph/unit/concurrent/LockGroupTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.baidu.hugegraph.unit.concurrent;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.junit.Test;
+
+import com.baidu.hugegraph.concurrent.AtomicLock;
+import com.baidu.hugegraph.concurrent.KeyLock;
+import com.baidu.hugegraph.concurrent.LockGroup;
+import com.baidu.hugegraph.testutil.Assert;
+
+public class LockGroupTest {
+
+    private static final String GROUP = "testGroup";
+
+    private LockGroup group = new LockGroup(GROUP);
+
+    @Test
+    public void testLock() {
+        Lock lock = this.group.lock("lock");
+        Assert.assertTrue(lock instanceof ReentrantLock);
+        Lock lock1 = this.group.lock("lock");
+        Assert.assertSame(lock, lock1);
+    }
+
+    @Test
+    public void testAtomicLock() {
+        AtomicLock lock = this.group.atomicLock("lock");
+        Assert.assertNotNull(lock);
+        AtomicLock lock1 = this.group.atomicLock("lock");
+        Assert.assertSame(lock, lock1);
+    }
+
+    @Test
+    public void testReadWriteLock() {
+        ReadWriteLock lock = this.group.readWriteLock("lock");
+        Assert.assertTrue(lock instanceof ReentrantReadWriteLock);
+        ReadWriteLock lock1 = this.group.readWriteLock("lock");
+        Assert.assertSame(lock, lock1);
+    }
+
+    @Test
+    public void testKeyLock() {
+        KeyLock lock = this.group.keyLock("lock");
+        Assert.assertNotNull(lock);
+        KeyLock lock1 = this.group.keyLock("lock");
+        Assert.assertSame(lock, lock1);
+    }
+
+    @Test
+    public void testName() {
+        Assert.assertEquals(GROUP, this.group.name());
+    }
+}