### Eclipse Workspace Patch 1.0 #P oak-core Index: src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java (revision 1526176) +++ src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java (working copy) @@ -17,6 +17,7 @@ package org.apache.jackrabbit.oak.security.authorization.permission; import java.security.Principal; +import java.util.HashMap; import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; @@ -117,9 +118,30 @@ public boolean hasPrivileges(@Nullable Tree tree, String... privilegeNames) { return compiledPermissions.hasPrivileges(tree, privilegeNames); } - + + private HashMap cache2 = new HashMap(); + @Override public ReadStatus getReadStatus(@Nonnull Tree tree, @Nullable PropertyState property) { + String key = ""; + if (tree != null) { + key += "tree: " + tree.getPath(); + } + if (property != null) { + key += "prop: " + property.getName(); + } + ReadStatus x = cache2.get(key); + if (x == null) { + x = getReadStatusUncached(tree, property); + cache2.put(key, x); + if (cache2.size() > 100 && cache2.size() % 100 == 0) { + System.out.println(cache2.size() + " " + key); + } + } + return x; + } + + private ReadStatus getReadStatusUncached(@Nonnull Tree tree, @Nullable PropertyState property) { int type = getType(tree, property); switch (type) { case TreeTypeProvider.TYPE_HIDDEN: Index: src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java (revision 1526176) +++ src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java (working copy) @@ -18,6 +18,7 @@ import java.security.Principal; import java.security.acl.Group; +import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; @@ -262,9 +263,38 @@ } return allowBits; } - + + private HashMap> cache = new HashMap>(); + @Nonnull private Iterator getEntryIterator(@Nonnull EntryPredicate predicate) { + String key = ""; + if (predicate.tree != null) { + key += "tree: " + predicate.tree.getPath(); + } + if (predicate.path != null) { + key += "path: " + predicate.path; + } + if (predicate.property != null) { + key += "prop: " + predicate.property.getName(); + } + ArrayList list = cache.get(key); + if (list == null) { + Iterator it = getEntryIteratorUncached(predicate); + list = new ArrayList(); + while (it.hasNext()) { + list.add(it.next()); + } + cache.put(key, list); + if (cache.size() > 100 && cache.size() % 100 == 0) { + System.out.println(cache.size() + " " + predicate); + } + } + return list.iterator(); + } + + @Nonnull + private Iterator getEntryIteratorUncached(@Nonnull EntryPredicate predicate) { Iterator userEntries = (userTrees.isEmpty()) ? Iterators.emptyIterator() : new EntryIterator(userTrees, predicate); @@ -338,23 +368,27 @@ private Iterator nextEntries = Iterators.emptyIterator(); // the next permission entry private PermissionEntry next; + private boolean init; private EntryIterator(@Nonnull Map principalTrees, @Nonnull EntryPredicate predicate) { this.principalTrees = principalTrees.values(); this.predicate = predicate; this.path = Strings.nullToEmpty(predicate.path); - next = seekNext(); } @Override public boolean hasNext() { + if (!init) { + init = true; + next = seekNext(); + } return next != null; } @Override public PermissionEntry next() { - if (next == null) { + if (!hasNext()) { throw new NoSuchElementException(); } @@ -386,8 +420,11 @@ @Nonnull private Iterator getNextEntries() { ImmutableSortedSet.Builder entries = new ImmutableSortedSet.Builder(new EntryComparator()); + String name = null; for (Tree principalRoot : principalTrees) { - String name = PermissionUtil.getEntryName(path); + if (name == null) { + name = PermissionUtil.getEntryName(path); + } Tree parent = principalRoot; while (parent.hasChild(name)) { parent = parent.getChild(name); Index: src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionUtil.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionUtil.java (revision 1526176) +++ src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionUtil.java (working copy) @@ -28,6 +28,9 @@ * PermissionUtil... TODO */ public final class PermissionUtil { + + private static final int CACHE_SIZE = 128; + private static final String[][] CACHE = new String[CACHE_SIZE][]; private PermissionUtil() {} @@ -39,6 +42,19 @@ @Nonnull public static String getEntryName(@Nullable String accessControlledPath) { String path = Strings.nullToEmpty(accessControlledPath); - return String.valueOf(path.hashCode()); + int fastHash = path.length() * 0x45d9f3b; + if (path.length() > 0) { + // last char + fastHash ^= path.charAt(path.length() - 1); + } + int index = fastHash & (CACHE_SIZE - 1); + String[] pair = CACHE[index]; + if (pair != null && path.equals(pair[0])) { + return pair[1]; + } + String result = String.valueOf(path.hashCode()); + pair = new String[]{path, result}; + CACHE[index] = pair; + return result; } } \ No newline at end of file