Skip to content

Commit

Permalink
Merge pull request #664 from rubnig/bugfix/663-prefetch-query-travers…
Browse files Browse the repository at this point in the history
…al-limit

[663] Fix prefetch query traversal limit
  • Loading branch information
ghenzler authored May 5, 2023
2 parents 620d540 + eece0cf commit bca7e04
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,10 @@ public AuthInstallerUserManagerPrefetchingImpl(UserManager delegate, final Value
Iterator<Authorizable> authorizablesToPrefetchIt = delegate.findAuthorizables(new Query() {
public <T> void build(QueryBuilder<T> builder) {
builder.setCondition(
builder.or( //
builder.neq("@" + JcrConstants.JCR_PRIMARYTYPE, valueFactory.createValue(UserConstants.NT_REP_USER)),
builder.eq("@" + UserConstants.REP_AUTHORIZABLE_ID, valueFactory.createValue(Constants.USER_ANONYMOUS))) //
builder.or(
builder.eq("@" + JcrConstants.JCR_PRIMARYTYPE, valueFactory.createValue(UserConstants.NT_REP_SYSTEM_USER)),
builder.eq("@" + JcrConstants.JCR_PRIMARYTYPE, valueFactory.createValue(UserConstants.NT_REP_GROUP))
)
);
}
});
Expand All @@ -81,22 +82,16 @@ public <T> void build(QueryBuilder<T> builder) {
long startPrefetchMemberships = System.currentTimeMillis();
while (authorizablesToPrefetchIt.hasNext()) {
Authorizable auth = authorizablesToPrefetchIt.next();
String authId = auth.getID();

// also cache those groups which are not member of any other group!
Set<String> memberOfByAuthorizableIds = new HashSet<>();
this.isMemberOfByAuthorizableId.put(authId, memberOfByAuthorizableIds);
Iterator<Group> declaredMemberOf = auth.declaredMemberOf();
while (declaredMemberOf.hasNext()) {
Group memberOfGroup = declaredMemberOf.next();
String memberOfGroupId = memberOfGroup.getID();
memberOfByAuthorizableIds.add(memberOfGroupId);
nonRegularUserMembersByAuthorizableId.computeIfAbsent(memberOfGroupId, id -> new HashSet<>()).add(authId);
membershipCount++;
}
membershipCount += prefetchAuthorizable(auth);
authorizableIdsAndPaths.put(auth.getID(), auth.getPath());
}

Authorizable anonymous = delegate.getAuthorizable(UserConstants.DEFAULT_ANONYMOUS_ID);
if (anonymous != null) {
membershipCount += prefetchAuthorizable(anonymous);
authorizableIdsAndPaths.put(anonymous.getID(), anonymous.getPath());
}

installLog.addMessage(LOG, "Prefetched " + membershipCount + " memberships in "
+ msHumanReadable(System.currentTimeMillis() - startPrefetchMemberships));
}
Expand Down Expand Up @@ -147,6 +142,27 @@ public void removeAuthorizable(final Authorizable authorizable) throws Repositor
authorizableIdsAndPaths.remove(authorizable.getID());
}

private int prefetchAuthorizable(final Authorizable authorizable) throws RepositoryException {
Objects.requireNonNull(authorizable);

int membershipCount = 0;
String authId = authorizable.getID();

// also cache those groups which are not member of any other group!
Set<String> memberOfByAuthorizableIds = new HashSet<>();
this.isMemberOfByAuthorizableId.put(authId, memberOfByAuthorizableIds);
Iterator<Group> declaredMemberOf = authorizable.declaredMemberOf();
while (declaredMemberOf.hasNext()) {
Group memberOfGroup = declaredMemberOf.next();
String memberOfGroupId = memberOfGroup.getID();
memberOfByAuthorizableIds.add(memberOfGroupId);
nonRegularUserMembersByAuthorizableId.computeIfAbsent(memberOfGroupId, id -> new HashSet<>()).add(authId);
membershipCount++;
}
authorizableIdsAndPaths.put(authorizable.getID(), authorizable.getPath());
return membershipCount;
}

private void removeGroupFromCache(final Group group) throws RepositoryException {
final String groupID = group.getID();
final Iterator<Authorizable> membersIt = group.getDeclaredMembers();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public class QueryHelper {
private static final String ROOT_REP_POLICY_NODE = "/rep:policy";
private static final String ROOT_REPO_POLICY_NODE = "/" + Constants.REPO_POLICY_NODE;
private static final String HOME_REP_POLICY = "/home/rep:policy";
private static final String OAK_INDEX_PATH_REP_ACL = "/oak:index/repACL";
private static final String OAK_INDEX_PATH_REP_ACL = "/oak:index/repACL-custom-1";

/** Method that returns a set containing all rep:policy nodes from repository excluding those contained in paths which are excluded from
* search
Expand Down

0 comments on commit bca7e04

Please sign in to comment.