Hi Stefan,
Thank you for the fast reply.
[...]
> > However I noticed an immense performance impact (about 500% in a
> > search) resulting from this because every getPath() call
> leads (in the
> > end) to a
> > load() call in the PersistenceManager.
> >
> > Unfortunately the caching mechanisms of jackrabbit (or any caching
> > mechanism) won't help me in the given scenario (a lot of
> nodes which
> > are accessed infrequently, frequent insertions into the repository).
> >
> > I would load the itemId -> path assignment at startup but as I
> > understand the architecture of the AccessManager it is neither
> > possible to get a list of all item ids nor is it possible to be
> > notified when a node is inserted to keep the cache up to date.
> >
[...]
> amContext.getHierarchyManager() does return an instance of
> o.a.j.core.CachingHierarchyManager which does, as its name
> implies, maintain a cache of id->path mappings which should
> prevent excessive path building.
Unfortunately this caching mechanism cannot be of much help in my scenario:
- Insertions into the repository are very frequent
- There is a great number of documents in the repository
- Typically queries matching the same documents are not repeated,
performance when on first execution of a query is the big issue
Bottom line is, cache hits will be the exception not the rule
> can you provide a simple
> test case that demontrates your issue?
I am afraid that will not be so easy since the application is wrapped up
quite tight, but I will try to assemble one in the next days.
Basically a test setup should not be very complicated:
- Repository containing ~ 25.000 nodes using SimpleDbPersistenceManager
attached to a MySQL DB
- Simple Custom AccessManager that only retrieves the path (see code below)
- Execute a contains query that matches a high number of rows but does not
iterate over them
- Deactivate Custom AccessManager (or simply remove the getPath statements
from isGranted/checkPermission)
- Execute same query and compare execution times (~6 seconds vs ~30 seconds
in my szenario)
AccessManager code:
public class DummyAccessManager implements AccessManager
{
private AMContext amContext;
public void init( AMContext accessManagerContext )
throws AccessDeniedException, Exception
{
this.amContext = accessManagerContext;
}
public void close() throws Exception
{
this.amContext = null;
}
public void checkPermission( ItemId id, int permissions )
throws AccessDeniedException,
ItemNotFoundException,
RepositoryException
{
this.amContext.getHierarchyManager().getPath( id );
}
public boolean isGranted( ItemId id, int permissions )
throws ItemNotFoundException, RepositoryException
{
this.amContext.getHierarchyManager().getPath( id );
return true;
}
public boolean canAccess( String workspaceName )
{
return true;
}
}
Regards
Daniel