Skip to content

JCRVLT-837 adding cached namespace impl to prevent thrashing in the r…#411

Open
pat-lego wants to merge 2 commits intoapache:masterfrom
pat-lego:support/cached-ns
Open

JCRVLT-837 adding cached namespace impl to prevent thrashing in the r…#411
pat-lego wants to merge 2 commits intoapache:masterfrom
pat-lego:support/cached-ns

Conversation

@pat-lego
Copy link
Copy Markdown

Avoid walking the JCR for namespaces.

Use a concurrent hash map to store the prefix and url in a map and update the map when necessary.

// Check if this aggregate's namespaces are already cached
String[] cachedPrefixes = mgr.getCachedAggregatePrefixes(path);
if (cachedPrefixes != null) {
log.debug("Using cached namespace prefixes for '{}': {}", path, cachedPrefixes);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICT, this code is never reached when running the filevault test suite.

We need a test case that actually covers this case.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a test

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I'm missing something, that code is never reached. Sonar agrees.

It would only help if the same path is scanned multiple times. If that can happen, we should be able to write a test.

* @param prefix the namespace prefix
* @return the namespace URI
* @throws RepositoryException if an error occurs
*/
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this better than using the JCR namespace registry? Why do we need a cache here?

* Cache of namespace prefixes per aggregate path. This cache stores the discovered prefixes
* for each aggregate path to avoid re-walking the same subtrees.
*/
private final ConcurrentHashMap<String, String[]> aggregateNamespaceCache = new ConcurrentHashMap<>();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an unbounded cache; and with a potentially very large amount of paths this can lead a huge memory consumption.

namespacePrefixes = prefixes.toArray(new String[prefixes.size()]);

// Cache the discovered prefixes for this aggregate path
mgr.cacheAggregatePrefixes(path, namespacePrefixes);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand this code correctly, it stores this String-Array of namespacePrefixes in a global cache, per path. But that also means, that there is benefit only in the case that loadNamespaces() is called at least twice (either as part of the same aggregate or in a different one). Under what circumstances would that be helpful then?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added bounded lru cache

@pat-lego
Copy link
Copy Markdown
Author

I added some optimizations to the code what would be interesting is to use this in the environment that is seeing the performance hit and see if there is an optimization

@reschke
Copy link
Copy Markdown
Contributor

reschke commented Jan 29, 2026

@pat-lego - this can be closed, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants