From bea3cbf2962641ff358818280116d1c7ee3e0579 Mon Sep 17 00:00:00 2001
From: Karolin Varner <karo@cupdev.net>
Date: Thu, 17 Feb 2022 14:36:40 +0100
Subject: [PATCH] OAK-9518: Benchmark of optimization: Do not refresh
 permissions for immutable mounts

---
 oak-benchmarks/metabenchmark.sh               | 45 +++++++++++++++++
 .../oak/benchmark/AbstractTest.java           |  1 -
 .../permission/MountPermissionProvider.java   |  9 +++-
 .../oak/fixture/CompositeStoreFixture.java    | 48 +++++++++++++++++++
 4 files changed, 100 insertions(+), 3 deletions(-)
 create mode 100755 oak-benchmarks/metabenchmark.sh

diff --git a/oak-benchmarks/metabenchmark.sh b/oak-benchmarks/metabenchmark.sh
new file mode 100755
index 0000000000..9a01a62bc2
--- /dev/null
+++ b/oak-benchmarks/metabenchmark.sh
@@ -0,0 +1,45 @@
+#! /bin/bash
+
+# Hello World
+
+exc() {
+  echo "\$ $@" >&2
+  "$@"
+}
+
+runBenchmark() {
+  pwd
+  exc java \
+    -Xmx2048m -Dprofile=false -Druntime=1200 -Dwarmup=10 \
+    -jar "${dir}/target/"oak-benchmarks-*-SNAPSHOT.jar benchmark \
+    --itemsToRead 10000 --concurrency 4 --batchSize 100 \
+    --csvFile "${dir}/metabench_$(date +'%Y%m%d_%H%M%S').csv" \
+    --importBehavior beesteffort --runAsAdmin false \
+    --report false --randomUser true --noIterations 20 \
+    --runWithToken 1 --expiration 200000 \
+    --numberOfGroups 50 --nestedGroups true \
+    "${1}" "Oak-Composite-Store" #Oak-Segment-Tar
+}
+
+listBenchmarks() {
+  grep -RPho 'public class\s+[A-Z][A-Za-z0-9_]*\s' "${dir}/src/main/java/org/apache/jackrabbit/oak/benchmark/" \
+    | sed 's@^public class @@' \
+    | grep -vP "ReplicaCrashResilienceTest|RemoveMembersTest|AddMembersTest|AddUniqueMembersTest|RemoveMemberTest|FlatTreeUpdateTest|AddMemberTest|SyncAllExternalUsersTest|SyncExternalUsersTest|SyncAllUsersTest|SetPropertyTest"
+}
+
+runAll() {
+  local bench
+  listBenchmarks | while read -r bench; do
+    exc runBenchmark "${bench}"
+  done
+}
+
+main() {
+  cd "${dir}"
+  local cmd; cmd="$1"; shift || cmd="runAll"
+  "${cmd}" "$@"
+}
+
+script="$0"
+dir="$(dirname "${script}")"
+main "$@"
diff --git a/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/AbstractTest.java b/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/AbstractTest.java
index 0da405a523..1f54af9eef 100644
--- a/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/AbstractTest.java
+++ b/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/AbstractTest.java
@@ -216,7 +216,6 @@ public abstract class AbstractTest<T> extends Benchmark implements CSVResultGene
 
         setUp(repository, CREDENTIALS);
         try {
-            
             if (!SKIP_WARMPUP) {
                 // Run a few iterations to warm up the system
                 long warmupEnd = System.currentTimeMillis() + WARMUP;
diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/MountPermissionProvider.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/MountPermissionProvider.java
index 9e915943ea..bfbc6ba690 100644
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/MountPermissionProvider.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/MountPermissionProvider.java
@@ -123,9 +123,14 @@ public class MountPermissionProvider extends PermissionProviderImpl {
 
         @Override
         public void flush(@NotNull Root root) {
-            for (PermissionStore store : stores) {
-                store.flush(root);
+            // Optimized variant
+            if (!stores.isEmpty()) {
+                  stores.get(0).flush(root);
             }
+            // Unoptimized variant
+            // for (PermissionStore store : stores) {
+                // store.flush(root);
+            // }
         }
     }
 }
diff --git a/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/fixture/CompositeStoreFixture.java b/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/fixture/CompositeStoreFixture.java
index c9ebe017f5..a4b7ccb4e0 100644
--- a/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/fixture/CompositeStoreFixture.java
+++ b/oak-run-commons/src/main/java/org/apache/jackrabbit/oak/fixture/CompositeStoreFixture.java
@@ -37,6 +37,36 @@ import org.apache.jackrabbit.oak.spi.mount.MountInfoProvider;
 import org.apache.jackrabbit.oak.spi.mount.Mounts;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.apache.jackrabbit.oak.InitialContent;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.spi.security.SecurityConfiguration;
+import org.apache.jackrabbit.oak.security.internal.SecurityProviderBuilder;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
+import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
+import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider;
+import org.apache.jackrabbit.oak.spi.commit.CompositeEditorProvider;
+import org.apache.jackrabbit.oak.plugins.name.NamespaceEditorProvider;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
+import org.apache.jackrabbit.oak.plugins.nodetype.TypeEditorProvider;
+import org.apache.jackrabbit.oak.OakInitializer;
+import org.apache.jackrabbit.oak.InitialContent;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import org.apache.jackrabbit.oak.fixture.JcrCreator;
+import javax.jcr.SimpleCredentials;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
+
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.Node;
+import javax.jcr.Session;
+import javax.jcr.security.AccessControlEntry;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.Privilege;
 
 import java.io.File;
 import java.io.IOException;
@@ -144,6 +174,9 @@ abstract class CompositeStoreFixture extends OakFixture {
     @Override
     public Oak getOak(int clusterId) throws Exception {
         MemoryNodeStore seed = new MemoryNodeStore();
+        EditorHook hook = new EditorHook(
+            new CompositeEditorProvider(new NamespaceEditorProvider(), new TypeEditorProvider()));
+        OakInitializer.initialize(seed, new InitialContent(), hook);
         Oak oakSeed = new Oak(seed);
         populateSeed(oakSeed);
 
@@ -166,6 +199,21 @@ abstract class CompositeStoreFixture extends OakFixture {
     // this method allows to populate the /apps and /libs subtrees, which becomes
     // immutable after the composite node store is created
     private void populateSeed(Oak oakSeed) {
+        try {
+            Repository repo = JcrCreator.DEFAULT.customize(oakSeed).createRepository();
+            Session session = repo.login(new SimpleCredentials("admin", "admin".toCharArray()));
+
+            Node mount = session.getRootNode().addNode("53ddc9e4-95b1-44a4-8b15-3c8a98022134", "nt:unstructured");
+            mount.addNode("2bec5aad-2c62-454b-a4c9-8093b3f5786e", "nt:unstructured");
+            for (int i = 0; i < 10000; i++) {
+                Node n = mount.addNode("6edee156-ef94-49e9-8bd1-f3af60c6a708-" + i, "nt:unstructured");
+                AccessControlUtils.grantAllToEveryone(session,
+                    n.getCorrespondingNodePath(session.getWorkspace().getName()));
+            }
+            session.save();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
     }
 
     @Override
-- 
2.35.1

