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();
