diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/utils/CompositeKey.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/utils/CompositeKey.java
index 2f54ae7c7019..ab8b244f1bfe 100644
--- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/utils/CompositeKey.java
+++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/utils/CompositeKey.java
@@ -18,53 +18,94 @@
package org.apache.hadoop.hdds.utils;
import java.util.Arrays;
+import java.util.Objects;
+import org.apache.ratis.util.Preconditions;
/**
* This is a utility to combine multiple objects as a key that can be used in
* hash map access. The advantage of this is that it is cheap in comparison
* to other methods like string concatenation.
- *
- * For example, if a composition of volume, bucket and key is needed to
- * access a hash map, the natural method is:
- *
{@code
- * String key = "/" + volume + "/" + bucket + "/" + key.
- * map.put(key, value);
- * }
- * This is costly because it creates (and stores) a new buffer.
- *
- * In comparison, the following achieve the same logic without creating any new
- * buffer.
- * {@code
- * Object key = combineKeys(volume, bucket, key).
- * map.put(key, value);
- * }
- *
*/
-public final class CompositeKey {
- private final int hashCode;
- private final Object[] components;
-
- CompositeKey(Object[] components) {
- this.components = components;
- this.hashCode = Arrays.hashCode(components);
+public abstract class CompositeKey {
+ /** The same as {@link Arrays#hashCode(Object[])} for one loop step. */
+ static int hash(int result, Object next) {
+ return 31 * result + next.hashCode();
}
- @Override
- public int hashCode() {
- return hashCode;
+ private static final class TwoComponents extends CompositeKey {
+ private final int hashCode;
+ private final Object first;
+ private final Object second;
+
+ private TwoComponents(Object first, Object second) {
+ this.first = Objects.requireNonNull(first, "first == null");
+ this.second = Objects.requireNonNull(second, "second == null");
+ this.hashCode = hash(hash(1, first), second);
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ } else if (!(obj instanceof TwoComponents)) {
+ return false;
+ }
+ final TwoComponents that = (TwoComponents) obj;
+ return this.hashCode == that.hashCode
+ && this.first.equals(that.first)
+ && this.second.equals(that.second);
+ }
}
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof CompositeKey)) {
- return false;
+ private static final class MultiComponents extends CompositeKey {
+ private final int hashCode;
+ private final Object[] components;
+
+ MultiComponents(Object[] components) {
+ Preconditions.assertTrue(components.length > 2, () -> "components.length " + components.length + " <= 2");
+ for (int i = 0; i < components.length; i++) {
+ final int j = i;
+ Objects.requireNonNull(components[j], () -> "components[" + j + "] == null");
+ }
+
+ this.hashCode = Arrays.hashCode(components);
+ this.components = components;
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ } else if (!(obj instanceof MultiComponents)) {
+ return false;
+ }
+ final MultiComponents that = (MultiComponents) obj;
+ return this.hashCode == that.hashCode
+ && Arrays.equals(this.components, that.components);
}
- CompositeKey other = (CompositeKey) obj;
- return Arrays.equals(components, other.components);
+ }
+
+ public static CompositeKey combineTwoKeys(Object first, Object second) {
+ return new TwoComponents(first, second);
+ }
+
+ public static CompositeKey combineMultiKeys(Object[] components) {
+ return new MultiComponents(components);
}
public static Object combineKeys(Object[] components) {
- return components.length == 1 ?
- components[0] : new CompositeKey(components);
+ return components.length == 1 ? components[0]
+ : components.length == 2 ? CompositeKey.combineTwoKeys(components[0], components[1])
+ : CompositeKey.combineMultiKeys(components);
}
}
diff --git a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/utils/TestCompositeKey.java b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/utils/TestCompositeKey.java
new file mode 100644
index 000000000000..c286d1e92590
--- /dev/null
+++ b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/utils/TestCompositeKey.java
@@ -0,0 +1,108 @@
+/*
+ * 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 org.apache.hadoop.hdds.utils;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Arrays;
+import java.util.Random;
+import org.junit.jupiter.api.Test;
+
+/** Test {@link CompositeKey}. */
+public final class TestCompositeKey {
+ private static final Random RANDOM = new Random();
+
+ static String randomString(int length) {
+ final StringBuilder builder = new StringBuilder(length);
+ for (int i = 0; i < length; i++) {
+ builder.append(RANDOM.nextInt(10));
+ }
+ return builder.toString();
+ }
+
+ static Object[] randomComponents(int numComponents) {
+ final Object[] components = new Object[numComponents];
+ for (int i = 0; i < components.length; i++) {
+ components[i] = randomString(RANDOM.nextInt(10));
+ }
+ return components;
+ }
+
+ private static final class OldCompositeKey {
+ private final int hashCode;
+ private final Object[] components;
+
+ OldCompositeKey(Object[] components) {
+ this.components = components;
+ this.hashCode = Arrays.hashCode(components);
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof OldCompositeKey)) {
+ return false;
+ }
+ OldCompositeKey other = (OldCompositeKey) obj;
+ return Arrays.equals(components, other.components);
+ }
+
+ static Object combineKeys(Object[] components) {
+ return components.length == 1 ?
+ components[0] : new OldCompositeKey(components);
+ }
+ }
+
+ static void assertHashCode(Object[] components, int computed) {
+ final Object expected = OldCompositeKey.combineKeys(components);
+ assertEquals(expected.hashCode(), CompositeKey.combineKeys(components).hashCode());
+ assertEquals(expected.hashCode(), computed);
+ }
+
+ @Test
+ public void testHashCodeOne() {
+ for (int i = 0; i < 100; i++) {
+ final Object[] components = {randomString(i)};
+ assertHashCode(components, components[0].hashCode());
+ }
+ }
+
+ @Test
+ public void testHashCodeTwo() {
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; j++) {
+ final Object first = randomString(i);
+ final Object second = randomString(j);
+ final Object[] components = {first, second};
+ assertHashCode(components, CompositeKey.combineTwoKeys(first, second).hashCode());
+ }
+ }
+ }
+
+ @Test
+ public void testHashCodeMulti() {
+ for (int i = 3; i < 100; i++) {
+ final Object[] components = randomComponents(i);
+ assertHashCode(components, CompositeKey.combineMultiKeys(components).hashCode());
+ }
+ }
+}
diff --git a/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/lock/IOzoneManagerLock.java b/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/lock/IOzoneManagerLock.java
index e9319a787e7c..167a09d96fd3 100644
--- a/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/lock/IOzoneManagerLock.java
+++ b/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/lock/IOzoneManagerLock.java
@@ -26,34 +26,52 @@
*/
public interface IOzoneManagerLock {
- OMLockDetails acquireReadLock(Resource resource,
- String... resources);
+ // ---------- acquireReadLock ----------
+ OMLockDetails acquireReadLock(Resource resource, String key);
+
+ OMLockDetails acquireReadLock(Resource resource, String key1, String key2);
+
+ OMLockDetails acquireReadLock(Resource resource, String... keys);
OMLockDetails acquireReadLocks(Resource resource, Iterable keys);
- OMLockDetails acquireWriteLock(Resource resource,
- String... resources);
+ // ---------- acquireWriteLock ----------
+ OMLockDetails acquireWriteLock(Resource resource, String key);
+
+ OMLockDetails acquireWriteLock(Resource resource, String key1, String key2);
+
+ OMLockDetails acquireWriteLock(Resource resource, String... keys);
OMLockDetails acquireWriteLocks(Resource resource, Iterable keys);
OMLockDetails acquireResourceWriteLock(Resource resource);
+ // ---------- MultiUserLock ----------
boolean acquireMultiUserLock(String firstUser, String secondUser);
void releaseMultiUserLock(String firstUser, String secondUser);
- OMLockDetails releaseWriteLock(Resource resource,
- String... resources);
+ // ---------- releaseWriteLock ----------
+ OMLockDetails releaseWriteLock(Resource resource, String key);
+
+ OMLockDetails releaseWriteLock(Resource resource, String key1, String key2);
+
+ OMLockDetails releaseWriteLock(Resource resource, String... keys);
OMLockDetails releaseWriteLocks(Resource resource, Iterable keys);
OMLockDetails releaseResourceWriteLock(Resource resource);
- OMLockDetails releaseReadLock(Resource resource,
- String... resources);
+ // ---------- releaseReadLock ----------
+ OMLockDetails releaseReadLock(Resource resource, String key);
+
+ OMLockDetails releaseReadLock(Resource resource, String key1, String key2);
+
+ OMLockDetails releaseReadLock(Resource resource, String... keys);
OMLockDetails releaseReadLocks(Resource resource, Iterable keys);
+ // ---------- other methods ----------
@VisibleForTesting
int getReadHoldCount(Resource resource,
String... resources);
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/lock/OBSKeyPathLockStrategy.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/lock/OBSKeyPathLockStrategy.java
index c715856db80f..f444589af95f 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/lock/OBSKeyPathLockStrategy.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/lock/OBSKeyPathLockStrategy.java
@@ -43,6 +43,7 @@ public OMLockDetails acquireWriteLock(OMMetadataManager omMetadataManager,
Preconditions.checkArgument(omLockDetails.isLockAcquired(),
"BUCKET_LOCK should be acquired!");
+ // TODO optimize three key case in similar way as HDDS-16059
omLockDetails.merge(omMetadataManager.getLock()
.acquireWriteLock(KEY_PATH_LOCK, volumeName, bucketName, keyName));
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/lock/OmReadOnlyLock.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/lock/OmReadOnlyLock.java
index 7e544b010202..96f84219601f 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/lock/OmReadOnlyLock.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/lock/OmReadOnlyLock.java
@@ -28,7 +28,17 @@
public class OmReadOnlyLock implements IOzoneManagerLock {
@Override
- public OMLockDetails acquireReadLock(Resource resource, String... resources) {
+ public OMLockDetails acquireReadLock(Resource resource, String key) {
+ return EMPTY_DETAILS_LOCK_ACQUIRED;
+ }
+
+ @Override
+ public OMLockDetails acquireReadLock(Resource resource, String key1, String key2) {
+ return EMPTY_DETAILS_LOCK_ACQUIRED;
+ }
+
+ @Override
+ public OMLockDetails acquireReadLock(Resource resource, String... keys) {
return EMPTY_DETAILS_LOCK_ACQUIRED;
}
@@ -38,8 +48,17 @@ public OMLockDetails acquireReadLocks(Resource resource, Iterable keys
}
@Override
- public OMLockDetails acquireWriteLock(Resource resource,
- String... resources) {
+ public OMLockDetails acquireWriteLock(Resource resource, String key) {
+ return EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
+ }
+
+ @Override
+ public OMLockDetails acquireWriteLock(Resource resource, String key1, String key2) {
+ return EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
+ }
+
+ @Override
+ public OMLockDetails acquireWriteLock(Resource resource, String... keys) {
return EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
}
@@ -64,8 +83,17 @@ public void releaseMultiUserLock(String firstUser, String secondUser) {
}
@Override
- public OMLockDetails releaseWriteLock(Resource resource,
- String... resources) {
+ public OMLockDetails releaseWriteLock(Resource resource, String key) {
+ return EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
+ }
+
+ @Override
+ public OMLockDetails releaseWriteLock(Resource resource, String key1, String key2) {
+ return EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
+ }
+
+ @Override
+ public OMLockDetails releaseWriteLock(Resource resource, String... keys) {
return EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
}
@@ -79,6 +107,16 @@ public OMLockDetails releaseResourceWriteLock(Resource resource) {
return EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
}
+ @Override
+ public OMLockDetails releaseReadLock(Resource resource, String key) {
+ return EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
+ }
+
+ @Override
+ public OMLockDetails releaseReadLock(Resource resource, String key1, String key2) {
+ return EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
+ }
+
@Override
public OMLockDetails releaseReadLock(Resource resource, String... resources) {
return EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/lock/OzoneManagerLock.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/lock/OzoneManagerLock.java
index a6a47844519b..1847dd31b7cc 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/lock/OzoneManagerLock.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/lock/OzoneManagerLock.java
@@ -124,11 +124,11 @@ R assertAcquire(Resource resource) {
private ReentrantReadWriteLock getLockForTesting(Resource resource, String... keys) {
final R r = Preconditions.assertInstanceOf(resource, tracker.getResourceClass());
- return getLock(r, keys);
+ return getLockWithCombinedKey(r, CompositeKey.combineKeys(keys));
}
- private ReentrantReadWriteLock getLock(R r, String... keys) {
- return lockMap.get(r).get(CompositeKey.combineKeys(keys));
+ private ReentrantReadWriteLock getLockWithCombinedKey(R r, Object combinedKey) {
+ return lockMap.get(r).get(combinedKey);
}
private void acquireLock(R resource, boolean isRead, ReentrantReadWriteLock lock, long startWaitingTimeNanos) {
@@ -148,9 +148,9 @@ private OMLockDetails acquireImpl(Resource resource, BiConsumer acquire
return tracker.lockResource(r);
}
- private OMLockDetails acquireOne(Resource resource, boolean isRead, String... keys) {
+ private OMLockDetails acquireOne(Resource resource, boolean isRead, Object combinedKey) {
return acquireImpl(resource, (r, startWaitingTimeNanos) -> {
- final ReentrantReadWriteLock lock = getLock(r, keys);
+ final ReentrantReadWriteLock lock = getLockWithCombinedKey(r, combinedKey);
acquireLock(r, isRead, lock, startWaitingTimeNanos);
});
}
@@ -190,9 +190,9 @@ private OMLockDetails releaseImpl(Resource resource, Consumer releaseLockMeth
return tracker.unlockResource(r);
}
- private OMLockDetails releaseOne(Resource resource, boolean isRead, String... keys) {
+ private OMLockDetails releaseOne(Resource resource, boolean isRead, Object combinedKey) {
return releaseImpl(resource, r -> {
- final ReentrantReadWriteLock lock = getLock(r, keys);
+ final ReentrantReadWriteLock lock = getLockWithCombinedKey(r, combinedKey);
releaseLock(r, isRead, lock);
});
}
@@ -305,73 +305,47 @@ public ReentrantReadWriteLock next() {
return deque::descendingIterator;
}
- /**
- * Acquire read lock on resource.
- *
- * For S3_BUCKET_LOCK, VOLUME_LOCK, BUCKET_LOCK type resource, same
- * thread acquiring lock again is allowed.
- *
- * For USER_LOCK, PREFIX_LOCK, S3_SECRET_LOCK type resource, same thread
- * acquiring lock again is not allowed.
- *
- * Special Note for USER_LOCK: Single thread can acquire single user lock/
- * multi user lock. But not both at the same time.
- * @param resource - Type of the resource.
- * @param keys - Resource names on which user want to acquire lock.
- * For Resource type BUCKET_LOCK, first param should be volume, second param
- * should be bucket name. For remaining all resource only one param should
- * be passed.
- */
+ @Override
+ public OMLockDetails acquireReadLock(Resource resource, String key) {
+ return getResourceLocks(resource)
+ .acquireOne(resource, true, key);
+ }
+
+ @Override
+ public OMLockDetails acquireReadLock(Resource resource, String key1, String key2) {
+ return getResourceLocks(resource)
+ .acquireOne(resource, true, CompositeKey.combineTwoKeys(key1, key2));
+ }
+
@Override
public OMLockDetails acquireReadLock(Resource resource, String... keys) {
+ Preconditions.assertTrue(keys.length > 2);
return getResourceLocks(resource)
- .acquireOne(resource, true, keys);
+ .acquireOne(resource, true, CompositeKey.combineMultiKeys(keys));
}
- /**
- * Acquire read locks on a list of resources.
- *
- * For S3_BUCKET_LOCK, VOLUME_LOCK, BUCKET_LOCK type resource, same
- * thread acquiring lock again is allowed.
- *
- * For USER_LOCK, PREFIX_LOCK, S3_SECRET_LOCK type resource, same thread
- * acquiring lock again is not allowed.
- *
- * Special Note for USER_LOCK: Single thread can acquire single user lock/
- * multi user lock. But not both at the same time.
- * @param resource - Type of the resource.
- * @param keys - A list of Resource names on which user want to acquire locks.
- * For Resource type BUCKET_LOCK, first param should be volume, second param
- * should be bucket name. For remaining all resource only one param should
- * be passed.
- */
@Override
public OMLockDetails acquireReadLocks(Resource resource, Iterable keys) {
return getResourceLocks(resource)
.acquireSelected(resource, true, keys);
}
- /**
- * Acquire write lock on resource.
- *
- * For S3_BUCKET_LOCK, VOLUME_LOCK, BUCKET_LOCK type resource, same
- * thread acquiring lock again is allowed.
- *
- * For USER_LOCK, PREFIX_LOCK, S3_SECRET_LOCK type resource, same thread
- * acquiring lock again is not allowed.
- *
- * Special Note for USER_LOCK: Single thread can acquire single user lock/
- * multi user lock. But not both at the same time.
- * @param resource - Type of the resource.
- * @param keys - Resource names on which user want to acquire lock.
- * For Resource type BUCKET_LOCK, first param should be volume, second param
- * should be bucket name. For remaining all resource only one param should
- * be passed.
- */
+ @Override
+ public OMLockDetails acquireWriteLock(Resource resource, String key) {
+ return getResourceLocks(resource)
+ .acquireOne(resource, false, key);
+ }
+
+ @Override
+ public OMLockDetails acquireWriteLock(Resource resource, String key1, String key2) {
+ return getResourceLocks(resource)
+ .acquireOne(resource, false, CompositeKey.combineTwoKeys(key1, key2));
+ }
+
@Override
public OMLockDetails acquireWriteLock(Resource resource, String... keys) {
return getResourceLocks(resource)
- .acquireOne(resource, false, keys);
+ .acquireOne(resource, false, CompositeKey.combineMultiKeys(keys));
}
/**
@@ -474,19 +448,22 @@ public void releaseMultiUserLock(String firstUser, String secondUser) {
Arrays.asList(new String[] {firstUser}, new String[] {secondUser}));
}
+ @Override
+ public OMLockDetails releaseWriteLock(Resource resource, String key) {
+ return getResourceLocks(resource)
+ .releaseOne(resource, false, key);
+ }
+
+ @Override
+ public OMLockDetails releaseWriteLock(Resource resource, String key1, String key2) {
+ return getResourceLocks(resource)
+ .releaseOne(resource, false, CompositeKey.combineTwoKeys(key1, key2));
+ }
- /**
- * Release write lock on resource.
- * @param resource - Type of the resource.
- * @param keys - Resource names on which user want to acquire lock.
- * For Resource type BUCKET_LOCK, first param should be volume, second param
- * should be bucket name. For remaining all resource only one param should
- * be passed.
- */
@Override
public OMLockDetails releaseWriteLock(Resource resource, String... keys) {
return getResourceLocks(resource)
- .releaseOne(resource, false, keys);
+ .releaseOne(resource, false, CompositeKey.combineMultiKeys(keys));
}
/**
@@ -514,18 +491,22 @@ public OMLockDetails releaseResourceWriteLock(Resource resource) {
.releaseAll(resource);
}
- /**
- * Release read lock on resource.
- * @param resource - Type of the resource.
- * @param keys - Resource names on which user want to acquire lock.
- * For Resource type BUCKET_LOCK, first param should be volume, second param
- * should be bucket name. For remaining all resource only one param should
- * be passed.
- */
+ @Override
+ public OMLockDetails releaseReadLock(Resource resource, String key) {
+ return getResourceLocks(resource)
+ .releaseOne(resource, true, key);
+ }
+
+ @Override
+ public OMLockDetails releaseReadLock(Resource resource, String key1, String key2) {
+ return getResourceLocks(resource)
+ .releaseOne(resource, true, CompositeKey.combineTwoKeys(key1, key2));
+ }
+
@Override
public OMLockDetails releaseReadLock(Resource resource, String... keys) {
return getResourceLocks(resource)
- .releaseOne(resource, true, keys);
+ .releaseOne(resource, true, CompositeKey.combineMultiKeys(keys));
}
/**
diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/lock/TestKeyPathLock.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/lock/TestKeyPathLock.java
index 77b7999d6162..eab2bd596645 100644
--- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/lock/TestKeyPathLock.java
+++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/lock/TestKeyPathLock.java
@@ -233,12 +233,11 @@ void testAcquireWriteBucketLockWhileAcquiredWriteKeyPathLock() {
OzoneManagerLock lock = new OzoneManagerLock(new OzoneConfiguration());
- String[] resourceName = new String[]{volumeName, bucketName, keyName},
- higherResourceName = new String[]{volumeName, bucketName};
+ String[] resourceName = new String[]{volumeName, bucketName, keyName};
lock.acquireWriteLock(resource, resourceName);
RuntimeException ex =
- assertThrows(RuntimeException.class, () -> lock.acquireWriteLock(higherResource, higherResourceName));
+ assertThrows(RuntimeException.class, () -> lock.acquireWriteLock(higherResource, volumeName, bucketName));
String message = "cannot acquire " + higherResource.getName() + " lock " +
"while holding [" + resource.getName() + "] lock(s).";
assertThat(ex).hasMessageContaining(message);
@@ -255,12 +254,11 @@ void testAcquireWriteBucketLockWhileAcquiredReadKeyPathLock() {
OzoneManagerLock lock = new OzoneManagerLock(new OzoneConfiguration());
- String[] resourceName = new String[]{volumeName, bucketName, keyName},
- higherResourceName = new String[]{volumeName, bucketName};
+ String[] resourceName = new String[]{volumeName, bucketName, keyName};
lock.acquireReadLock(resource, resourceName);
- RuntimeException ex =
- assertThrows(RuntimeException.class, () -> lock.acquireWriteLock(higherResource, higherResourceName));
+ RuntimeException ex = assertThrows(RuntimeException.class,
+ () -> lock.acquireWriteLock(higherResource, volumeName, bucketName));
String message = "cannot acquire " + higherResource.getName() + " lock " +
"while holding [" + resource.getName() + "] lock(s).";
assertThat(ex).hasMessageContaining(message);
@@ -277,12 +275,11 @@ void testAcquireReadBucketLockWhileAcquiredReadKeyPathLock() {
OzoneManagerLock lock = new OzoneManagerLock(new OzoneConfiguration());
- String[] resourceName = new String[]{volumeName, bucketName, keyName},
- higherResourceName = new String[]{volumeName, bucketName};
+ String[] resourceName = new String[]{volumeName, bucketName, keyName};
lock.acquireReadLock(resource, resourceName);
RuntimeException ex =
- assertThrows(RuntimeException.class, () -> lock.acquireReadLock(higherResource, higherResourceName));
+ assertThrows(RuntimeException.class, () -> lock.acquireReadLock(higherResource, volumeName, bucketName));
String message = "cannot acquire " + higherResource.getName() + " lock " +
"while holding [" + resource.getName() + "] lock(s).";
assertThat(ex).hasMessageContaining(message);
@@ -299,12 +296,11 @@ void testAcquireReadBucketLockWhileAcquiredWriteKeyPathLock() {
OzoneManagerLock lock = new OzoneManagerLock(new OzoneConfiguration());
- String[] resourceName = new String[]{volumeName, bucketName, keyName},
- higherResourceName = new String[]{volumeName, bucketName};
+ String[] resourceName = new String[]{volumeName, bucketName, keyName};
lock.acquireWriteLock(resource, resourceName);
RuntimeException ex =
- assertThrows(RuntimeException.class, () -> lock.acquireReadLock(higherResource, higherResourceName));
+ assertThrows(RuntimeException.class, () -> lock.acquireReadLock(higherResource, volumeName, bucketName));
String message = "cannot acquire " + higherResource.getName() + " lock " +
"while holding [" + resource.getName() + "] lock(s).";
assertThat(ex).hasMessageContaining(message);
diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/lock/TestOzoneManagerLock.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/lock/TestOzoneManagerLock.java
index 5aaab032b32f..3f275671eb61 100644
--- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/lock/TestOzoneManagerLock.java
+++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/lock/TestOzoneManagerLock.java
@@ -67,8 +67,8 @@ void acquireResourceLock(LeveledResource resource) {
private void testResourceLock(String[] resourceName, LeveledResource resource) {
OzoneManagerLock lock = new OzoneManagerLock(new OzoneConfiguration());
- lock.acquireWriteLock(resource, resourceName);
- assertDoesNotThrow(() -> lock.releaseWriteLock(resource, resourceName));
+ acquireWriteLock(lock, resource, resourceName);
+ assertDoesNotThrow(() -> releaseWriteLock(lock, resource, resourceName));
}
@ParameterizedTest
@@ -86,18 +86,18 @@ private void testResourceReacquireLock(String[] resourceName,
if (resource == LeveledResource.USER_LOCK ||
resource == LeveledResource.S3_SECRET_LOCK ||
resource == LeveledResource.PREFIX_LOCK) {
- lock.acquireWriteLock(resource, resourceName);
+ acquireWriteLock(lock, resource, resourceName);
RuntimeException ex =
- assertThrows(RuntimeException.class, () -> lock.acquireWriteLock(resource, resourceName));
+ assertThrows(RuntimeException.class, () -> acquireWriteLock(lock, resource, resourceName));
String message = "cannot acquire " + resource.getName() + " lock " +
"while holding [" + resource.getName() + "] lock(s).";
assertThat(ex).hasMessageContaining(message);
- assertDoesNotThrow(() -> lock.releaseWriteLock(resource, resourceName));
+ assertDoesNotThrow(() -> releaseWriteLock(lock, resource, resourceName));
} else {
- lock.acquireWriteLock(resource, resourceName);
- lock.acquireWriteLock(resource, resourceName);
- assertDoesNotThrow(() -> lock.releaseWriteLock(resource, resourceName));
- assertDoesNotThrow(() -> lock.releaseWriteLock(resource, resourceName));
+ acquireWriteLock(lock, resource, resourceName);
+ acquireWriteLock(lock, resource, resourceName);
+ assertDoesNotThrow(() -> releaseWriteLock(lock, resource, resourceName));
+ assertDoesNotThrow(() -> releaseWriteLock(lock, resource, resourceName));
}
}
@@ -112,12 +112,12 @@ void testLockingOrder() {
for (LeveledResource resource : LeveledResource.values()) {
Stack stack = new Stack<>();
resourceName = generateResourceName(resource);
- lock.acquireWriteLock(resource, resourceName);
+ acquireWriteLock(lock, resource, resourceName);
stack.push(new ResourceInfo(resourceName, resource));
for (LeveledResource higherResource : LeveledResource.values()) {
if (higherResource.getMask() > resource.getMask()) {
resourceName = generateResourceName(higherResource);
- lock.acquireWriteLock(higherResource, resourceName);
+ acquireWriteLock(lock, higherResource, resourceName);
stack.push(new ResourceInfo(resourceName, higherResource));
}
}
@@ -125,7 +125,7 @@ void testLockingOrder() {
while (!stack.empty()) {
ResourceInfo resourceInfo = stack.pop();
assertDoesNotThrow(() ->
- lock.releaseWriteLock(resourceInfo.getResource(), resourceInfo.getLockName()));
+ releaseWriteLock(lock, resourceInfo.getResource(), resourceInfo.getLockName()));
}
}
}
@@ -144,19 +144,19 @@ public void testDAGLockWithParallelResource(DAGLeveledResource dagLeveledResourc
for (Resource otherResource : resources) {
String[] otherResourceName = generateResourceName(otherResource);
String[] dagResourceName = generateResourceName(dagLeveledResource);
- lock.acquireWriteLock(otherResource, otherResourceName);
+ acquireWriteLock(lock, otherResource, otherResourceName);
boolean secondLockAcquired = false;
try {
if (forbiddenLockOrdering.getOrDefault(dagLeveledResource, Collections.emptySet()).contains(otherResource)) {
- assertThrows(RuntimeException.class, () -> lock.acquireWriteLock(dagLeveledResource, dagResourceName));
+ assertThrows(RuntimeException.class, () -> acquireWriteLock(lock, dagLeveledResource, dagResourceName));
} else {
- lock.acquireWriteLock(dagLeveledResource, dagResourceName);
+ acquireWriteLock(lock, dagLeveledResource, dagResourceName);
secondLockAcquired = true;
}
} finally {
- lock.releaseWriteLock(otherResource, otherResourceName);
+ releaseWriteLock(lock, otherResource, otherResourceName);
if (secondLockAcquired) {
- lock.releaseWriteLock(dagLeveledResource, dagResourceName);
+ releaseWriteLock(lock, dagLeveledResource, dagResourceName);
}
}
}
@@ -169,15 +169,15 @@ void testLockViolationsWithOneHigherLevelLock(LeveledResource resource) {
for (LeveledResource higherResource : LeveledResource.values()) {
if (higherResource.getMask() > resource.getMask()) {
String[] resourceName = generateResourceName(higherResource);
- lock.acquireWriteLock(higherResource, resourceName);
+ acquireWriteLock(lock, higherResource, resourceName);
try {
Exception e = assertThrows(RuntimeException.class,
- () -> lock.acquireWriteLock(resource, generateResourceName(resource)));
+ () -> acquireWriteLock(lock, resource, generateResourceName(resource)));
String message = "cannot acquire " + resource.getName() + " lock " +
"while holding [" + higherResource.getName() + "] lock(s).";
assertThat(e).hasMessageContaining(message);
} finally {
- lock.releaseWriteLock(higherResource, resourceName);
+ releaseWriteLock(lock, higherResource, resourceName);
}
}
}
@@ -197,13 +197,13 @@ void testLockViolations() {
for (LeveledResource higherResource : LeveledResource.values()) {
if (higherResource.getMask() > resource.getMask()) {
resourceName = generateResourceName(higherResource);
- lock.acquireWriteLock(higherResource, resourceName);
+ acquireWriteLock(lock, higherResource, resourceName);
stack.push(new ResourceInfo(resourceName, higherResource));
currentLocks.add(higherResource.getName());
// try to acquire lower level lock
RuntimeException ex = assertThrows(RuntimeException.class, () -> {
String[] resourceName1 = generateResourceName(resource);
- lock.acquireWriteLock(resource, resourceName1);
+ acquireWriteLock(lock, resource, resourceName1);
});
String message = "cannot acquire " + resource.getName() + " lock " +
"while holding " + currentLocks + " lock(s).";
@@ -214,7 +214,7 @@ void testLockViolations() {
// Now release locks
while (!stack.empty()) {
ResourceInfo resourceInfo = stack.pop();
- lock.releaseWriteLock(resourceInfo.getResource(),
+ releaseWriteLock(lock, resourceInfo.getResource(),
resourceInfo.getLockName());
}
}
@@ -225,7 +225,7 @@ void releaseLockWithOutAcquiringLock() {
OzoneManagerLock lock =
new OzoneManagerLock(new OzoneConfiguration());
assertThrows(IllegalMonitorStateException.class,
- () -> lock.releaseWriteLock(LeveledResource.USER_LOCK, "user3"));
+ () -> releaseWriteLock(lock, LeveledResource.USER_LOCK, "user3"));
}
private String[] generateResourceName(Resource resource) {
@@ -241,6 +241,46 @@ private String[] generateResourceName(Resource resource) {
}
}
+ static void acquireReadLock(OzoneManagerLock lock, Resource resource, String... keys) {
+ if (keys.length == 1) {
+ lock.acquireReadLock(resource, keys[0]);
+ } else if (keys.length == 2) {
+ lock.acquireReadLock(resource, keys[0], keys[1]);
+ } else {
+ lock.acquireReadLock(resource, keys);
+ }
+ }
+
+ static void acquireWriteLock(OzoneManagerLock lock, Resource resource, String... keys) {
+ if (keys.length == 1) {
+ lock.acquireWriteLock(resource, keys[0]);
+ } else if (keys.length == 2) {
+ lock.acquireWriteLock(resource, keys[0], keys[1]);
+ } else {
+ lock.acquireWriteLock(resource, keys);
+ }
+ }
+
+ static void releaseWriteLock(OzoneManagerLock lock, Resource resource, String... keys) {
+ if (keys.length == 1) {
+ lock.releaseWriteLock(resource, keys[0]);
+ } else if (keys.length == 2) {
+ lock.releaseWriteLock(resource, keys[0], keys[1]);
+ } else {
+ lock.releaseWriteLock(resource, keys);
+ }
+ }
+
+ static void releaseReadLock(OzoneManagerLock lock, Resource resource, String... keys) {
+ if (keys.length == 1) {
+ lock.releaseReadLock(resource, keys[0]);
+ } else if (keys.length == 2) {
+ lock.releaseReadLock(resource, keys[0], keys[1]);
+ } else {
+ lock.releaseReadLock(resource, keys);
+ }
+ }
+
/**
* Class used to store locked resource info.
*/
@@ -283,12 +323,12 @@ void reAcquireMultiUserLock() {
@Test
void acquireMultiUserLockAfterUserLock() {
OzoneManagerLock lock = new OzoneManagerLock(new OzoneConfiguration());
- lock.acquireWriteLock(LeveledResource.USER_LOCK, "user3");
+ acquireWriteLock(lock, LeveledResource.USER_LOCK, "user3");
Exception e = assertThrows(RuntimeException.class,
() -> lock.acquireMultiUserLock("user1", "user2"));
assertThat(e)
.hasMessageContaining("cannot acquire USER_LOCK lock while holding [USER_LOCK] lock(s).");
- lock.releaseWriteLock(LeveledResource.USER_LOCK, "user3");
+ releaseWriteLock(lock, LeveledResource.USER_LOCK, "user3");
}
@Test
@@ -296,7 +336,7 @@ void acquireUserLockAfterMultiUserLock() {
OzoneManagerLock lock = new OzoneManagerLock(new OzoneConfiguration());
lock.acquireMultiUserLock("user1", "user2");
Exception e = assertThrows(RuntimeException.class,
- () -> lock.acquireWriteLock(LeveledResource.USER_LOCK, "user3"));
+ () -> acquireWriteLock(lock, LeveledResource.USER_LOCK, "user3"));
assertThat(e)
.hasMessageContaining("cannot acquire USER_LOCK lock while holding [USER_LOCK] lock(s).");
lock.releaseMultiUserLock("user1", "user2");
@@ -313,7 +353,7 @@ void testLockResourceParallel(boolean fullResourceLock) throws Exception {
if (fullResourceLock) {
lock.acquireResourceWriteLock(resource);
} else {
- lock.acquireWriteLock(resource, resourceName);
+ acquireWriteLock(lock, resource, resourceName);
}
AtomicBoolean gotLock = new AtomicBoolean(false);
@@ -321,13 +361,13 @@ void testLockResourceParallel(boolean fullResourceLock) throws Exception {
if (fullResourceLock) {
lock.acquireResourceWriteLock(resource);
} else {
- lock.acquireWriteLock(resource, resourceName);
+ acquireWriteLock(lock, resource, resourceName);
}
gotLock.set(true);
if (fullResourceLock) {
lock.releaseResourceWriteLock(resource);
} else {
- lock.releaseWriteLock(resource, resourceName);
+ releaseWriteLock(lock, resource, resourceName);
}
}).start();
@@ -339,7 +379,7 @@ void testLockResourceParallel(boolean fullResourceLock) throws Exception {
if (fullResourceLock) {
lock.releaseResourceWriteLock(resource);
} else {
- lock.releaseWriteLock(resource, resourceName);
+ releaseWriteLock(lock, resource, resourceName);
}
// Since we have released the lock, the new thread should have the lock
// now.
@@ -367,9 +407,9 @@ void testResourceLockFullResourceLockParallel(boolean mainThreadAcquireResourceL
lock.acquireResourceWriteLock(resource);
} else {
if (acquireWriteLock) {
- lock.acquireWriteLock(resource, resourceName);
+ acquireWriteLock(lock, resource, resourceName);
} else {
- lock.acquireReadLock(resource, resourceName);
+ acquireReadLock(lock, resource, resourceName);
}
}
@@ -379,9 +419,9 @@ void testResourceLockFullResourceLockParallel(boolean mainThreadAcquireResourceL
lock.acquireResourceWriteLock(resource);
} else {
if (acquireWriteLock) {
- lock.acquireWriteLock(resource, resourceName);
+ acquireWriteLock(lock, resource, resourceName);
} else {
- lock.acquireReadLock(resource, resourceName);
+ acquireReadLock(lock, resource, resourceName);
}
}
gotLock.set(true);
@@ -389,9 +429,9 @@ void testResourceLockFullResourceLockParallel(boolean mainThreadAcquireResourceL
lock.releaseResourceWriteLock(resource);
} else {
if (acquireWriteLock) {
- lock.releaseWriteLock(resource, resourceName);
+ releaseWriteLock(lock, resource, resourceName);
} else {
- lock.releaseReadLock(resource, resourceName);
+ releaseReadLock(lock, resource, resourceName);
}
}
}).start();
@@ -404,9 +444,9 @@ void testResourceLockFullResourceLockParallel(boolean mainThreadAcquireResourceL
lock.releaseResourceWriteLock(resource);
} else {
if (acquireWriteLock) {
- lock.releaseWriteLock(resource, resourceName);
+ releaseWriteLock(lock, resource, resourceName);
} else {
- lock.releaseReadLock(resource, resourceName);
+ releaseReadLock(lock, resource, resourceName);
}
}
// Since we have released the lock, the new thread should have the lock
@@ -486,33 +526,33 @@ private void testLockHoldCountUtil(LeveledResource resource,
OzoneManagerLock lock = new OzoneManagerLock(new OzoneConfiguration());
assertEquals(0, lock.getReadHoldCount(resource, resourceName));
- lock.acquireReadLock(resource, resourceName);
+ acquireReadLock(lock, resource, resourceName);
assertEquals(1, lock.getReadHoldCount(resource, resourceName));
- lock.acquireReadLock(resource, resourceName);
+ acquireReadLock(lock, resource, resourceName);
assertEquals(2, lock.getReadHoldCount(resource, resourceName));
- lock.releaseReadLock(resource, resourceName);
+ releaseReadLock(lock, resource, resourceName);
assertEquals(1, lock.getReadHoldCount(resource, resourceName));
- lock.releaseReadLock(resource, resourceName);
+ releaseReadLock(lock, resource, resourceName);
assertEquals(0, lock.getReadHoldCount(resource, resourceName));
assertFalse(lock.isWriteLockedByCurrentThread(resource, resourceName));
assertEquals(0, lock.getWriteHoldCount(resource, resourceName));
- lock.acquireWriteLock(resource, resourceName);
+ acquireWriteLock(lock, resource, resourceName);
assertTrue(lock.isWriteLockedByCurrentThread(resource, resourceName));
assertEquals(1, lock.getWriteHoldCount(resource, resourceName));
- lock.acquireWriteLock(resource, resourceName);
+ acquireWriteLock(lock, resource, resourceName);
assertTrue(lock.isWriteLockedByCurrentThread(resource, resourceName));
assertEquals(2, lock.getWriteHoldCount(resource, resourceName));
- lock.releaseWriteLock(resource, resourceName);
+ releaseWriteLock(lock, resource, resourceName);
assertTrue(lock.isWriteLockedByCurrentThread(resource, resourceName));
assertEquals(1, lock.getWriteHoldCount(resource, resourceName));
- lock.releaseWriteLock(resource, resourceName);
+ releaseWriteLock(lock, resource, resourceName);
assertFalse(lock.isWriteLockedByCurrentThread(resource, resourceName));
assertEquals(0, lock.getWriteHoldCount(resource, resourceName));
}
@@ -535,13 +575,13 @@ private void testReadLockConcurrentStats(LeveledResource resource,
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(() -> {
- lock.acquireReadLock(resource, resourceName);
+ acquireReadLock(lock, resource, resourceName);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
- lock.releaseReadLock(resource, resourceName);
+ releaseReadLock(lock, resource, resourceName);
});
threads[i].start();
}
@@ -567,13 +607,13 @@ private void testWriteLockConcurrentStats(LeveledResource resource,
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(() -> {
- lock.acquireWriteLock(resource, resourceName);
+ acquireWriteLock(lock, resource, resourceName);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
- lock.releaseWriteLock(resource, resourceName);
+ releaseWriteLock(lock, resource, resourceName);
});
threads[i].start();
}
@@ -600,13 +640,13 @@ private void testSyntheticReadWriteLockConcurrentStats(
for (int i = 0; i < readThreads.length; i++) {
readThreads[i] = new Thread(() -> {
- lock.acquireReadLock(resource, resourceName);
+ acquireReadLock(lock, resource, resourceName);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
- lock.releaseReadLock(resource, resourceName);
+ releaseReadLock(lock, resource, resourceName);
});
readThreads[i].setName("ReadLockThread-" + i);
readThreads[i].start();
@@ -614,13 +654,13 @@ private void testSyntheticReadWriteLockConcurrentStats(
for (int i = 0; i < writeThreads.length; i++) {
writeThreads[i] = new Thread(() -> {
- lock.acquireWriteLock(resource, resourceName);
+ acquireWriteLock(lock, resource, resourceName);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
- lock.releaseWriteLock(resource, resourceName);
+ releaseWriteLock(lock, resource, resourceName);
});
writeThreads[i].setName("WriteLockThread-" + i);
writeThreads[i].start();
diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestSnapshotCache.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestSnapshotCache.java
index 96fdb35d4679..2c789729c063 100644
--- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestSnapshotCache.java
+++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestSnapshotCache.java
@@ -518,16 +518,32 @@ void testSnapshotOperationsNotBlockedDuringCompaction() throws IOException, Inte
private static IOzoneManagerLock newAcquiringLock() {
IOzoneManagerLock acquiringLock = mock(IOzoneManagerLock.class);
+ when(acquiringLock.acquireReadLock(eq(SNAPSHOT_DB_LOCK), any(String.class)))
+ .thenReturn(OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED);
+ when(acquiringLock.acquireReadLock(eq(SNAPSHOT_DB_LOCK), any(String.class), any(String.class)))
+ .thenReturn(OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED);
when(acquiringLock.acquireReadLock(eq(SNAPSHOT_DB_LOCK), any(String[].class)))
.thenReturn(OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED);
+ when(acquiringLock.releaseReadLock(eq(SNAPSHOT_DB_LOCK), any(String.class)))
+ .thenReturn(OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED);
+ when(acquiringLock.releaseReadLock(eq(SNAPSHOT_DB_LOCK), any(String.class), any(String.class)))
+ .thenReturn(OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED);
when(acquiringLock.releaseReadLock(eq(SNAPSHOT_DB_LOCK), any(String[].class)))
.thenReturn(OMLockDetails.EMPTY_DETAILS_LOCK_NOT_ACQUIRED);
when(acquiringLock.acquireResourceWriteLock(eq(SNAPSHOT_DB_LOCK)))
.thenReturn(OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED);
when(acquiringLock.releaseResourceWriteLock(eq(SNAPSHOT_DB_LOCK)))
.thenReturn(OMLockDetails.EMPTY_DETAILS_LOCK_NOT_ACQUIRED);
+ when(acquiringLock.acquireWriteLock(eq(SNAPSHOT_DB_LOCK), any(String.class)))
+ .thenReturn(OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED);
+ when(acquiringLock.acquireWriteLock(eq(SNAPSHOT_DB_LOCK), any(String.class), any(String.class)))
+ .thenReturn(OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED);
when(acquiringLock.acquireWriteLock(eq(SNAPSHOT_DB_LOCK), any(String[].class)))
.thenReturn(OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED);
+ when(acquiringLock.releaseWriteLock(eq(SNAPSHOT_DB_LOCK), any(String.class)))
+ .thenReturn(OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED);
+ when(acquiringLock.releaseWriteLock(eq(SNAPSHOT_DB_LOCK), any(String.class), any(String.class)))
+ .thenReturn(OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED);
when(acquiringLock.releaseWriteLock(eq(SNAPSHOT_DB_LOCK), any(String[].class)))
.thenReturn(OMLockDetails.EMPTY_DETAILS_LOCK_NOT_ACQUIRED);
return acquiringLock;