You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2014/12/16 18:18:37 UTC

svn commit: r1646014 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/ oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/

Author: angela
Date: Tue Dec 16 17:18:37 2014
New Revision: 1646014

URL: http://svn.apache.org/r1646014
Log:
OAK-2350: Improve performance of user query with scope set

Added:
    jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/FindAuthorizableWithScopeTest.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/GroupPredicate.java
    jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/GroupPredicate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/GroupPredicate.java?rev=1646014&r1=1646013&r2=1646014&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/GroupPredicate.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/GroupPredicate.java Tue Dec 16 17:18:37 2014
@@ -16,10 +16,16 @@
  */
 package org.apache.jackrabbit.oak.security.user.query;
 
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import javax.jcr.RepositoryException;
 
 import com.google.common.base.Predicate;
+import com.google.common.collect.Iterators;
 import org.apache.jackrabbit.api.security.user.Authorizable;
 import org.apache.jackrabbit.api.security.user.Group;
 import org.apache.jackrabbit.api.security.user.UserManager;
@@ -33,24 +39,51 @@ class GroupPredicate implements Predicat
 
     static final Logger log = LoggerFactory.getLogger(GroupPredicate.class);
 
-    private final Group group;
-    private final boolean declaredMembersOnly;
+    private final Iterator<Authorizable> membersIterator;
+    private final Set<String> memberIds = new HashSet<String>();
 
     GroupPredicate(UserManager userManager, String groupId, boolean declaredMembersOnly) throws RepositoryException {
         Authorizable authorizable = userManager.getAuthorizable(groupId);
-        group = (authorizable == null || !authorizable.isGroup()) ? null : (Group) authorizable;
-        this.declaredMembersOnly = declaredMembersOnly;
+        Group group = (authorizable == null || !authorizable.isGroup()) ? null : (Group) authorizable;
+        if (group != null) {
+            membersIterator = (declaredMembersOnly) ? group.getDeclaredMembers() : group.getMembers();
+        } else {
+            membersIterator = Iterators.emptyIterator();
+        }
     }
 
     @Override
     public boolean apply(@Nullable Authorizable authorizable) {
-        if (group != null && authorizable != null) {
+        if (authorizable != null) {
             try {
-                return (declaredMembersOnly) ? group.isDeclaredMember(authorizable) : group.isMember(authorizable);
+                String id = authorizable.getID();
+                if (memberIds.contains(id)) {
+                    return true;
+                } else {
+                    while (membersIterator.hasNext()) {
+                        String memberId = saveGetId(membersIterator.next());
+                        if (memberId != null) {
+                            memberIds.add(memberId);
+                            if (memberId.equals(id)) {
+                                return true;
+                            }
+                        }
+                    }
+                }
             } catch (RepositoryException e) {
                 log.debug("Cannot determine group membership for {}", authorizable, e.getMessage());
             }
         }
         return false;
     }
+
+    @CheckForNull
+    private String saveGetId(@Nonnull Authorizable authorizable) {
+        try {
+            return authorizable.getID();
+        } catch (RepositoryException e) {
+            log.debug("Error while retrieving ID for authorizable {}", authorizable, e.getMessage());
+        }
+        return null;
+    }
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java?rev=1646014&r1=1646013&r2=1646014&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java Tue Dec 16 17:18:37 2014
@@ -101,6 +101,9 @@ public class BenchmarkRunner {
                 .withOptionalArg().ofType(Boolean.class).defaultsTo(Boolean.FALSE);
         OptionSpec<Integer> numberOfUsers = parser.accepts("numberOfUsers")
                 .withOptionalArg().ofType(Integer.class).defaultsTo(10000);
+        OptionSpec<Boolean> setScope = parser.accepts("setScope", "Whether to use include setScope in the user query.")
+                        .withOptionalArg().ofType(Boolean.class)
+                        .defaultsTo(Boolean.FALSE);
         OptionSpec<String> nonOption = parser.nonOptions();
         OptionSpec help = parser.acceptsAll(asList("h", "?", "help"), "show help").forHelp();
         OptionSet options = parser.parse(args);
@@ -263,7 +266,8 @@ public class BenchmarkRunner {
             new FullTextSearchTest(
                     wikipedia.value(options),
                     flatStructure.value(options),
-                    report.value(options), withStorage.value(options))
+                    report.value(options), withStorage.value(options)),
+            new FindAuthorizableWithScopeTest(numberOfUsers.value(options), setScope.value(options))
         };
 
         Set<String> argset = Sets.newHashSet(nonOption.values(options));

Added: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/FindAuthorizableWithScopeTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/FindAuthorizableWithScopeTest.java?rev=1646014&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/FindAuthorizableWithScopeTest.java (added)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/FindAuthorizableWithScopeTest.java Tue Dec 16 17:18:37 2014
@@ -0,0 +1,101 @@
+/*
+ * 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.jackrabbit.oak.benchmark;
+
+import java.util.Iterator;
+import javax.jcr.Node;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.Query;
+import org.apache.jackrabbit.api.security.user.QueryBuilder;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.util.Text;
+
+public class FindAuthorizableWithScopeTest extends AbstractTest {
+
+    private static final String GROUP_ID = "testGroup";
+
+    private final long numberOfUsers;
+    private final boolean setScope;
+
+    private Session adminSession;
+    private UserManager userMgr;
+
+    public FindAuthorizableWithScopeTest(long numberOfUsers, boolean setScope) {
+        this.numberOfUsers = numberOfUsers;
+        this.setScope = setScope;
+    }
+
+    @Override
+    protected void beforeSuite() throws Exception {
+        adminSession = loginWriter();
+
+        userMgr = ((JackrabbitSession) adminSession).getUserManager();
+        Group gr = userMgr.createGroup(GROUP_ID, new PrincipalImpl(GROUP_ID), "test");
+        for (int i = 0; i < numberOfUsers; i++) {
+            User u = userMgr.createUser("testUser" + i, null, new PrincipalImpl("testUser" + i), "test");
+            gr.addMember(u);
+        }
+        adminSession.save();
+    }
+
+    @Override
+    protected void afterSuite() throws Exception {
+        Authorizable gr = userMgr.getAuthorizable(GROUP_ID);
+        if (gr != null) {
+            Node n = adminSession.getNode(Text.getRelativeParent(gr.getPath(), 1));
+            n.remove();
+        }
+        Authorizable u1 = userMgr.getAuthorizable("testUser0");
+        if (u1 != null) {
+            Node n = adminSession.getNode(Text.getRelativeParent(u1.getPath(), 1));
+            n.remove();
+        }
+        adminSession.save();
+    }
+
+    @Override
+    protected void runTest() throws Exception {
+        Iterator<Authorizable> result = userMgr.findAuthorizables(createQuery());
+
+        while (result.hasNext()) {
+            result.next();
+        }
+    }
+
+    private Query createQuery() {
+        if (setScope) {
+            return new Query() {
+                public <T> void build(QueryBuilder<T> builder) {
+                    builder.nameMatches("testUser");
+                    builder.setScope(GROUP_ID, true);
+                }
+            };
+        } else {
+            return new Query() {
+                public <T> void build(QueryBuilder<T> builder) {
+                    builder.nameMatches("testUser");
+                }
+            };
+        }
+    }
+}
\ No newline at end of file