This is an automated email from the ASF dual-hosted git repository.

daim pushed a commit to branch OAK-11720
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git

commit 679bca5cfe8b8b5cc7e5e5a32ffe3cb32e617444
Author: Rishabh Kumar <[email protected]>
AuthorDate: Tue May 13 15:13:45 2025 +0530

    OAK-11720 : added OSGI config to avoid taking exclusive merge lock in case 
of conflicts
---
 .../oak/plugins/document/Configuration.java        |  8 ++++
 .../oak/plugins/document/DocumentNodeStore.java    |  8 +++-
 .../plugins/document/DocumentNodeStoreBranch.java  |  9 ++--
 .../plugins/document/DocumentNodeStoreBuilder.java | 20 +++++++++
 .../plugins/document/DocumentNodeStoreService.java | 12 ++++-
 .../document/rdb/RDBDocumentNodeStoreBuilder.java  | 22 ++++++++++
 .../oak/plugins/document/util/Utils.java           | 11 +++++
 .../DocumentNodeStoreServiceConfigurationTest.java | 10 +++++
 .../mongo/MongoDocumentNodeStoreBuilderTest.java   | 12 +++++
 .../rdb/RDBDocumentNodeStoreBuilderTest.java       | 16 +++++++
 .../oak/plugins/document/util/UtilsTest.java       | 51 ++++++++++++++++++++++
 11 files changed, 174 insertions(+), 5 deletions(-)

diff --git 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
index 48be6afe0e..3fc0a58403 100644
--- 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
+++ 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
@@ -34,6 +34,7 @@ import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilde
 import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder.DEFAULT_NODE_CACHE_PERCENTAGE;
 import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder.DEFAULT_PREV_DOC_CACHE_PERCENTAGE;
 import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder.DEFAULT_UPDATE_LIMIT;
+import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_AVOID_MERGE_LOCK;
 import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_FULL_GC_ENABLED;
 import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_EMBEDDED_VERIFICATION_ENABLED;
 import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_FULL_GC_GENERATION;
@@ -417,4 +418,11 @@ import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreServic
         name = "Enable Full GC Persistent Audit Logging",
         description = "This parameter will enable/disable the saving of 
deleted document IDs and properties during FullGC into a persistent storage, 
e.g Mongo collection")
     boolean fullGCAuditLoggingEnabled() default false;
+
+    @AttributeDefinition(
+            name = "Avoid Exclusive Merge lock",
+            description = "Boolean value indicating whether we need to avoid 
the exclusive merge lock while " +
+                    "merging the changes in case of a conflict. The Default 
value is " + DEFAULT_AVOID_MERGE_LOCK +
+                    " Note that this value can be overridden via framework 
property 'oak.documentstore.avoidMergeLock'")
+    boolean avoidMergeLock() default DEFAULT_AVOID_MERGE_LOCK;
 }
diff --git 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
index f013b393b9..5bc96c08f8 100644
--- 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
+++ 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
@@ -33,6 +33,7 @@ import static 
org.apache.jackrabbit.oak.plugins.document.Path.ROOT;
 import static 
org.apache.jackrabbit.oak.plugins.document.util.Utils.alignWithExternalRevisions;
 import static 
org.apache.jackrabbit.oak.plugins.document.util.Utils.getIdFromPath;
 import static 
org.apache.jackrabbit.oak.plugins.document.util.Utils.getModuleVersion;
+import static 
org.apache.jackrabbit.oak.plugins.document.util.Utils.isAvoidMergeLockEnabled;
 import static 
org.apache.jackrabbit.oak.plugins.document.util.Utils.isFullGCEnabled;
 import static 
org.apache.jackrabbit.oak.plugins.document.util.Utils.isEmbeddedVerificationEnabled;
 import static 
org.apache.jackrabbit.oak.plugins.document.util.Utils.isThrottlingEnabled;
@@ -405,6 +406,10 @@ public final class DocumentNodeStore
      */
     private final ReadWriteLock mergeLock = new ReentrantReadWriteLock();
 
+    /**
+     * To avoid taking exclusive merge lock while merging changes into 
repository in case of conflict
+     */
+    private final boolean avoidMergeLock;
     /**
      * Enable using simple revisions (just a counter). This feature is useful
      * for testing.
@@ -641,6 +646,7 @@ public final class DocumentNodeStore
         this.prefetchFeature = builder.getPrefetchFeature();
         this.cancelInvalidationFeature = 
builder.getCancelInvalidationFeature();
         this.noChildOrderCleanupFeature = 
builder.getNoChildOrderCleanupFeature();
+        this.avoidMergeLock = isAvoidMergeLockEnabled(builder);
         this.cacheWarming = new CacheWarming(s);
 
         this.journalPropertyHandlerFactory = 
builder.getJournalPropertyHandlerFactory();
@@ -1898,7 +1904,7 @@ public final class DocumentNodeStore
 
     @NotNull
     DocumentNodeStoreBranch createBranch(DocumentNodeState base) {
-        return new DocumentNodeStoreBranch(this, base, mergeLock);
+        return new DocumentNodeStoreBranch(this, base, mergeLock, 
avoidMergeLock);
     }
 
     @NotNull
diff --git 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java
 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java
index 24c98a52ce..705982c0e8 100644
--- 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java
+++ 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java
@@ -75,6 +75,7 @@ class DocumentNodeStoreBranch implements NodeStoreBranch {
 
     /** The maximum number of updates to keep in memory */
     private final int updateLimit;
+    private final boolean avoidMergeLock;
 
     /**
      * State of the this branch. Either {@link Unmodified}, {@link InMemory}, 
{@link Persisted},
@@ -85,13 +86,15 @@ class DocumentNodeStoreBranch implements NodeStoreBranch {
 
     DocumentNodeStoreBranch(DocumentNodeStore store,
                             DocumentNodeState base,
-                            ReadWriteLock mergeLock) {
+                            ReadWriteLock mergeLock,
+                            boolean avoidMergeLock) {
         this.store = requireNonNull(store);
         this.branchState = new Unmodified(requireNonNull(base));
         this.maximumBackoff = Math.max((long) store.getMaxBackOffMillis(), 
MIN_BACKOFF);
         this.maxLockTryTimeMS = (long) (store.getMaxBackOffMillis() * 
MAX_LOCK_TRY_TIME_MULTIPLIER);
         this.mergeLock = mergeLock;
         this.updateLimit = store.getUpdateLimit();
+        this.avoidMergeLock = avoidMergeLock;
     }
 
     @NotNull
@@ -122,9 +125,9 @@ class DocumentNodeStoreBranch implements NodeStoreBranch {
                 throw e;
             }
         }
-        // retry with exclusive lock, blocking other
+        // retry with exclusive lock (if avoidMergeLock is not enabled), 
blocking other
         // concurrent writes
-        return merge0(hook, info, true);
+        return merge0(hook, info, !avoidMergeLock);
     }
 
     @Override
diff --git 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBuilder.java
 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBuilder.java
index 671a4b594e..18c0503c16 100644
--- 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBuilder.java
+++ 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBuilder.java
@@ -136,6 +136,7 @@ public class DocumentNodeStoreBuilder<T extends 
DocumentNodeStoreBuilder<T>> {
     private Feature cancelInvalidationFeature;
     private Feature docStoreFullGCFeature;
     private Feature docStoreEmbeddedVerificationFeature;
+    private Feature docStoreAvoidMergeLockFeature;
     private Feature prevNoPropCacheFeature;
     private Weigher<CacheValue, CacheValue> weigher = new EmpiricalWeigher();
     private long memoryCacheSize = DEFAULT_MEMORY_CACHE_SIZE;
@@ -176,6 +177,7 @@ public class DocumentNodeStoreBuilder<T extends 
DocumentNodeStoreBuilder<T>> {
     private Predicate<Path> nodeCachePredicate = x -> true;
     private boolean clusterInvisible;
     private boolean throttlingEnabled;
+    private boolean avoidMergeLock;
     private boolean fullGCEnabled;
     private Set<String> fullGCIncludePaths = Set.of();
     private Set<String> fullGCExcludePaths = Set.of();
@@ -310,6 +312,15 @@ public class DocumentNodeStoreBuilder<T extends 
DocumentNodeStoreBuilder<T>> {
         return this.throttlingEnabled;
     }
 
+    public T setAvoidMergeLock(boolean b) {
+        this.avoidMergeLock = b;
+        return thisBuilder();
+    }
+
+    public boolean avoidMergeLock() {
+        return this.avoidMergeLock;
+    }
+
     public T setFullGCEnabled(boolean b) {
         this.fullGCEnabled = b;
         return thisBuilder();
@@ -496,6 +507,15 @@ public class DocumentNodeStoreBuilder<T extends 
DocumentNodeStoreBuilder<T>> {
         return docStoreEmbeddedVerificationFeature;
     }
 
+    public Feature getDocStoreAvoidMergeLockFeature() {
+        return docStoreAvoidMergeLockFeature;
+    }
+
+    public T setDocStoreAvoidMergeLockFeature(@Nullable Feature 
docStoreAvoidMergeLock) {
+        this.docStoreAvoidMergeLockFeature = docStoreAvoidMergeLock;
+        return thisBuilder();
+    }
+
     public T setPrevNoPropCacheFeature(@Nullable Feature 
prevNoPropCacheFeature) {
         this.prevNoPropCacheFeature = prevNoPropCacheFeature;
         return thisBuilder();
diff --git 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
index b666795a54..27219d54c7 100644
--- 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
+++ 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
@@ -157,6 +157,7 @@ public class DocumentNodeStoreService {
     static final long DEFAULT_JOURNAL_GC_INTERVAL_MILLIS = 5*60*1000; // 
default is 5min
     static final long DEFAULT_JOURNAL_GC_MAX_AGE_MILLIS = 24*60*60*1000; // 
default is 24hours
     static final boolean DEFAULT_PREFETCH_EXTERNAL_CHANGES = false;
+    static final boolean DEFAULT_AVOID_MERGE_LOCK = false;
     private static final String DEFAULT_PROP_HOME = "./repository";
     static final long DEFAULT_MAX_REPLICATION_LAG = 6 * 60 * 60;
     static final boolean DEFAULT_BUNDLING_DISABLED = false;
@@ -204,6 +205,11 @@ public class DocumentNodeStoreService {
      */
     private static final String FT_NAME_FULL_GC = "FT_FULL_GC_OAK-10199";
 
+    /**
+     * Feature toggle name to avoid exclusive merge lock for merging changes 
in repository in case of a conflict
+     */
+    private static final String FT_NAME_AVOID_MERGE_LOCK = 
"FT_AVOID_MERGE_LOCK_OAK-11720";
+
     /**
      * Feature toggle name to enable embedded verification for full GC mode 
for Mongo Document Store
      */
@@ -257,6 +263,7 @@ public class DocumentNodeStoreService {
     private Feature cancelInvalidationFeature;
     private Feature docStoreFullGCFeature;
     private Feature docStoreEmbeddedVerificationFeature;
+    private Feature docStoreAvoidMergeLockFeature;
     private Feature prevNoPropCacheFeature;
     private ComponentContext context;
     private Whiteboard whiteboard;
@@ -296,6 +303,7 @@ public class DocumentNodeStoreService {
         cancelInvalidationFeature = 
Feature.newFeature(FT_NAME_CANCEL_INVALIDATION, whiteboard);
         docStoreFullGCFeature = Feature.newFeature(FT_NAME_FULL_GC, 
whiteboard);
         docStoreEmbeddedVerificationFeature = 
Feature.newFeature(FT_NAME_EMBEDDED_VERIFICATION, whiteboard);
+        docStoreAvoidMergeLockFeature = 
Feature.newFeature(FT_NAME_AVOID_MERGE_LOCK, whiteboard);
         prevNoPropCacheFeature = 
Feature.newFeature(FT_NAME_PREV_NO_PROP_CACHE, whiteboard);
 
         registerNodeStoreIfPossible();
@@ -524,8 +532,10 @@ public class DocumentNodeStoreService {
                 setCancelInvalidationFeature(cancelInvalidationFeature).
                 setDocStoreFullGCFeature(docStoreFullGCFeature).
                 
setDocStoreEmbeddedVerificationFeature(docStoreEmbeddedVerificationFeature).
+                
setDocStoreAvoidMergeLockFeature(docStoreAvoidMergeLockFeature).
                 setPrevNoPropCacheFeature(prevNoPropCacheFeature).
                 setThrottlingEnabled(config.throttlingEnabled()).
+                setAvoidMergeLock(config.avoidMergeLock()).
                 setFullGCEnabled(config.fullGCEnabled()).
                 setFullGCIncludePaths(config.fullGCIncludePaths()).
                 setFullGCExcludePaths(config.fullGCExcludePaths()).
@@ -681,7 +691,7 @@ public class DocumentNodeStoreService {
         }
 
         closeFeatures(prefetchFeature, docStoreThrottlingFeature, 
cancelInvalidationFeature, docStoreFullGCFeature,
-                docStoreEmbeddedVerificationFeature, prevNoPropCacheFeature);
+                docStoreEmbeddedVerificationFeature, prevNoPropCacheFeature, 
docStoreAvoidMergeLockFeature);
 
         unregisterNodeStore();
     }
diff --git 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilder.java
 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilder.java
index b8223fd599..cede15f1b7 100644
--- 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilder.java
+++ 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilder.java
@@ -136,6 +136,17 @@ public class RDBDocumentNodeStoreBuilder
         return thisBuilder();
     }
 
+    @Override
+    public RDBDocumentNodeStoreBuilder setAvoidMergeLock(boolean b) {
+        return thisBuilder();
+    }
+
+    @Override
+    public boolean avoidMergeLock() {
+        // setting this is not supported for RDB
+        return false;
+    }
+
     @Override
     public boolean isFullGCAuditLoggingEnabled() {
         // fullGC is non supported for RDB
@@ -208,6 +219,17 @@ public class RDBDocumentNodeStoreBuilder
         // fullGC max age is not supported for RDB
         return 0;
     }
+
+    @Override
+    public RDBDocumentNodeStoreBuilder 
setDocStoreAvoidMergeLockFeature(@Nullable Feature docStoreAvoidMergeLock) {
+        return thisBuilder();
+    }
+
+    @Override
+    @Nullable
+    public Feature getDocStoreAvoidMergeLockFeature() {
+        return null;
+    }
   
     @Override
     public RDBDocumentNodeStoreBuilder setDocStoreFullGCFeature(@Nullable 
Feature docStoreFullGC) {
diff --git 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/Utils.java
 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/Utils.java
index 8b56fe89b3..4a99c7a0d3 100644
--- 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/Utils.java
+++ 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/Utils.java
@@ -1129,6 +1129,17 @@ public class Utils {
         return builder.isEmbeddedVerificationEnabled() || 
(docStoreEmbeddedVerificationFeature != null && 
docStoreEmbeddedVerificationFeature.isEnabled());
     }
 
+    /**
+     * Check whether avoid exclusive merge lock is enabled or not for document 
store.
+     *
+     * @param builder instance for DocumentNodeStoreBuilder
+     * @return true if avoid exclusive merge lock is enabled else false
+     */
+    public static boolean isAvoidMergeLockEnabled(final 
DocumentNodeStoreBuilder<?> builder) {
+        final Feature docStoreAvoidMergeLockFeature = 
builder.getDocStoreAvoidMergeLockFeature();
+        return builder.avoidMergeLock() || (docStoreAvoidMergeLockFeature != 
null && docStoreAvoidMergeLockFeature.isEnabled());
+    }
+
     /**
      * Returns true if all the revisions in the {@code a} greater or equals
      * to their counterparts in {@code b}. If {@code b} contains revisions
diff --git 
a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java
 
b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java
index 1516626a85..e15ed89a43 100644
--- 
a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java
+++ 
b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java
@@ -34,6 +34,7 @@ import org.osgi.service.cm.ConfigurationAdmin;
 import org.osgi.service.component.ComponentContext;
 
 import static java.util.List.of;
+import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_AVOID_MERGE_LOCK;
 import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_FGC_BATCH_SIZE;
 import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_FGC_DELAY_FACTOR;
 import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_FGC_PROGRESS_SIZE;
@@ -95,6 +96,7 @@ public class DocumentNodeStoreServiceConfigurationTest {
         assertEquals(of("/"), of(config.fullGCIncludePaths()));
         assertEquals(of(), of(config.fullGCExcludePaths()));
         assertEquals("STRICT", config.leaseCheckMode());
+        assertEquals(DEFAULT_AVOID_MERGE_LOCK, config.avoidMergeLock());
         assertEquals(DEFAULT_THROTTLING_ENABLED, config.throttlingEnabled());
         assertEquals(DEFAULT_FULL_GC_ENABLED, config.fullGCEnabled());
         assertEquals(DEFAULT_FULL_GC_MODE, config.fullGCMode());
@@ -125,6 +127,14 @@ public class DocumentNodeStoreServiceConfigurationTest {
         assertEquals(throttleDocStore, config.throttlingEnabled());
     }
 
+    @Test
+    public void avoidMergeLockEnabled() throws Exception {
+        boolean avoidMergeLock = true;
+        addConfigurationEntry(preset, "avoidMergeLock", avoidMergeLock);
+        Configuration config = createConfiguration();
+        assertEquals(avoidMergeLock, config.avoidMergeLock());
+    }
+
     @Test
     public void fullGCEnabled() throws Exception {
         boolean fullGCDocStore = true;
diff --git 
a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilderTest.java
 
b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilderTest.java
index 340d62ca6b..16736f3880 100644
--- 
a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilderTest.java
+++ 
b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilderTest.java
@@ -44,6 +44,12 @@ public class MongoDocumentNodeStoreBuilderTest {
         assertFalse(builder.isThrottlingEnabled());
     }
 
+    @Test
+    public void avoidMergeLockDisabled() {
+        MongoDocumentNodeStoreBuilder builder = new 
MongoDocumentNodeStoreBuilder();
+        assertFalse(builder.avoidMergeLock());
+    }
+
     @Test
     public void throttlingFeatureToggleDisabled() {
         MongoDocumentNodeStoreBuilder builder = new 
MongoDocumentNodeStoreBuilder();
@@ -114,6 +120,12 @@ public class MongoDocumentNodeStoreBuilderTest {
         assertNull(builder.getDocStoreEmbeddedVerificationFeature());
     }
 
+    @Test
+    public void avoidMergeLockFeatureToggleEnabled() {
+        MongoDocumentNodeStoreBuilder builder = new 
MongoDocumentNodeStoreBuilder();
+        assertNull(builder.getDocStoreAvoidMergeLockFeature());
+    }
+
     @Test
     public void getPrevNoPropCacheFeatureDisabled() {
         MongoDocumentNodeStoreBuilder builder = new 
MongoDocumentNodeStoreBuilder();
diff --git 
a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilderTest.java
 
b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilderTest.java
index fa0f2479e9..8323d01563 100755
--- 
a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilderTest.java
+++ 
b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilderTest.java
@@ -69,6 +69,13 @@ public class RDBDocumentNodeStoreBuilderTest {
         assertFalse(builder.isFullGCEnabled());
     }
 
+    @Test
+    public void avoidMergeLockDisabled() {
+        RDBDocumentNodeStoreBuilder builder = new 
RDBDocumentNodeStoreBuilder();
+        builder.setAvoidMergeLock(true);
+        assertFalse(builder.avoidMergeLock());
+    }
+
     @Test
     public void fullGCIncludePathsEmpty() {
         RDBDocumentNodeStoreBuilder builder = new 
RDBDocumentNodeStoreBuilder();
@@ -108,6 +115,15 @@ public class RDBDocumentNodeStoreBuilderTest {
         assertNull(builder.getDocStoreEmbeddedVerificationFeature());
     }
 
+    @Test
+    public void avoidMergeLockFeatureToggleDisabled() {
+        RDBDocumentNodeStoreBuilder builder = new 
RDBDocumentNodeStoreBuilder();
+        Feature avoidMergeLockFeature = mock(Feature.class);
+        when(avoidMergeLockFeature.isEnabled()).thenReturn(true);
+        builder.setDocStoreAvoidMergeLockFeature(avoidMergeLockFeature);
+        assertNull(builder.getDocStoreAvoidMergeLockFeature());
+    }
+
     @Test
     public void fullGCModeHasDefaultValue() {
         RDBDocumentNodeStoreBuilder builder = new 
RDBDocumentNodeStoreBuilder();
diff --git 
a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/UtilsTest.java
 
b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/UtilsTest.java
index 2ec1de9e3d..5f8ab1329b 100644
--- 
a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/UtilsTest.java
+++ 
b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/UtilsTest.java
@@ -57,6 +57,7 @@ import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilde
 import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder.DEFAULT_PREV_NO_PROP_CACHE_PERCENTAGE;
 import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder.newDocumentNodeStoreBuilder;
 import static 
org.apache.jackrabbit.oak.plugins.document.rdb.RDBDocumentNodeStoreBuilder.newRDBDocumentNodeStoreBuilder;
+import static 
org.apache.jackrabbit.oak.plugins.document.util.Utils.isAvoidMergeLockEnabled;
 import static 
org.apache.jackrabbit.oak.plugins.document.util.Utils.isFullGCEnabled;
 import static 
org.apache.jackrabbit.oak.plugins.document.util.Utils.isEmbeddedVerificationEnabled;
 import static 
org.apache.jackrabbit.oak.plugins.document.util.Utils.isThrottlingEnabled;
@@ -236,6 +237,56 @@ public class UtilsTest {
         assertFalse("Full GC is disabled for RDB Document Store", 
fullGCEnabled);
     }
 
+    @Test
+    public void avoidMergeLockEnabledDefaultValue() {
+        boolean avoidMergeLockEnabled = 
isAvoidMergeLockEnabled(newDocumentNodeStoreBuilder());
+        assertFalse("Avoid Merge Lock is enabled by default", 
avoidMergeLockEnabled);
+    }
+
+    @Test
+    public void avoidMergeLockExplicitlyDisabled() {
+        DocumentNodeStoreBuilder<?> builder = newDocumentNodeStoreBuilder();
+        builder.setAvoidMergeLock(false);
+        Feature docStoreAvoidMergeLockFeature = mock(Feature.class);
+        when(docStoreAvoidMergeLockFeature.isEnabled()).thenReturn(false);
+        
builder.setDocStoreAvoidMergeLockFeature(docStoreAvoidMergeLockFeature);
+        boolean avoidMergeLockEnabled = isAvoidMergeLockEnabled(builder);
+        assertFalse("Avoid Merge Lock is disabled explicitly", 
avoidMergeLockEnabled);
+    }
+
+    @Test
+    public void avoidMergeLockEnabledViaConfiguration() {
+        DocumentNodeStoreBuilder<?> builder = newDocumentNodeStoreBuilder();
+        builder.setAvoidMergeLock(true);
+        Feature docStoreAvoidMergeLockFeature = mock(Feature.class);
+        when(docStoreAvoidMergeLockFeature.isEnabled()).thenReturn(false);
+        
builder.setDocStoreAvoidMergeLockFeature(docStoreAvoidMergeLockFeature);
+        boolean avoidMergeLockEnabled = isAvoidMergeLockEnabled(builder);
+        assertTrue("Avoid Merge Lock is enabled via configuration", 
avoidMergeLockEnabled);
+    }
+
+    @Test
+    public void avoidMergeLockEnabledViaFeatureToggle() {
+        DocumentNodeStoreBuilder<?> builder = newDocumentNodeStoreBuilder();
+        builder.setAvoidMergeLock(false);
+        Feature docStoreAvoidMergeLockFeature = mock(Feature.class);
+        when(docStoreAvoidMergeLockFeature.isEnabled()).thenReturn(true);
+        
builder.setDocStoreAvoidMergeLockFeature(docStoreAvoidMergeLockFeature);
+        boolean avoidMergeLockEnabled = isAvoidMergeLockEnabled(builder);
+        assertTrue("Avoid Merge Lock is enabled via Feature Toggle", 
avoidMergeLockEnabled);
+    }
+
+    @Test
+    public void avoidMergeLockDisabledForRDB() {
+        DocumentNodeStoreBuilder<?> builder = newRDBDocumentNodeStoreBuilder();
+        builder.setAvoidMergeLock(true);
+        Feature docStoreAvoidMergeLockFeature = mock(Feature.class);
+        when(docStoreAvoidMergeLockFeature.isEnabled()).thenReturn(true);
+        
builder.setDocStoreAvoidMergeLockFeature(docStoreAvoidMergeLockFeature);
+        boolean avoidMergeLockEnabled = isAvoidMergeLockEnabled(builder);
+        assertFalse("Avoid Merge Lock is enabled for RDB Document Store", 
avoidMergeLockEnabled);
+    }
+
     @Test
     public void fullGCModeDefaultValue() {
         DocumentNodeStoreBuilder<?> builder = newDocumentNodeStoreBuilder();

Reply via email to