[ 
https://issues.apache.org/jira/browse/JCR-688?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12462760
 ] 

Jukka Zitting commented on JCR-688:
-----------------------------------

Attached a JCR-688.NameResolver.patch that includes 1) a proposed new 
NameResolver interface, and 2) a generational name cache. For now the patch 
simply replaces the CachingNamespaceResolver class, but if the NameResolver 
proposal gets accepted, it has potential to simplify quite a lot of the current 
name resolution code.

1) NameResolver interface

The previous and current mechanisms of putting JCR name parsing and formatting 
operations respectively in the NamespaceResolver interface and the NameFormat 
static class are both not very clean. The methods in NamespaceResolver imply 
extra responsibilities even to classes that would only need to handle namespace 
mappings and not individual names, and the static NameFormat methods are very 
inflexible, for example support for name caching requires explicit instanceof 
operations.

The NameResolver interface is a proposal to simplify this. The interface 
implies only the responsibilities of parsing and formatting JCR names and 
leaves the handling of namespace mappings or name caching as implementation 
details.

I've included two basic implementations of the NameResolver interface in the 
patch: the ParsingNameResolver class contains the basic name parsing and 
formatting routines and uses a NamespaceResolver to access the prefix mappings, 
while the CachingNameResolver class can be used to decorate another 
NameResolver (most likely a ParsingNameResolver) with name caching. Those two 
implementations should be enough to cover almost all of the current name 
resolution needs.

2) Generational name cache

Both the LRUMap and ConcurrentReaderHashMap alternatives cause the entire name 
cache to get flushed when a client generates a long sequence of different 
names, for example "itemN" where N is a sequence number. To better handle this 
situation and to get rid of all synchronization for most cases, the 
CachingNameResolver class implements a "generational" name cache that borrows 
ideas from modern garbage collectors.

The basic idea of a generational name cache is that there are three cache maps: 
one is a long term cache and two represent "generations" of cached entries, one 
"young" and one "old" generation. Name entries in the long term cache are 
always looked up and returned directly without any synchronization or counting 
taking place. If the long term cache is missed, the entry is looked up in 
either of the generations or explicitly resolved using the decorated 
NameResolver. Finally the resolved name entry added to the "young" generation 
to mark it as recently requested.

After a configurable number of such long term cache misses (the "age" of the 
generation) have been made, the union of the two generations is calculated and 
added to the long term cache. I.e. the names that have been accessed 
continuously over two cache generations will probably be used frequently in the 
long term. Then the previous "young" generation is becomes the new "old" 
generation, and a new empty "young" generation is started. Once the long term 
cache reaches a specified maximum size, it gets replaced with just the union of 
the last two generations.

The CachingNameResolver is also implemented so that no synchronization is 
required for accessing the long term cache. Synchronization is only used when a 
long term cache miss occurs and even then concurrent reads to the long term 
cache can continue.


> Improve name resolution
> -----------------------
>
>                 Key: JCR-688
>                 URL: https://issues.apache.org/jira/browse/JCR-688
>             Project: Jackrabbit
>          Issue Type: Improvement
>          Components: core
>            Reporter: Jukka Zitting
>            Priority: Minor
>             Fix For: 1.3
>
>         Attachments: JCR-688.LocalCache.patch, JCR-688.NameResolver.patch
>
>
> As discussed in JCR-685, the current CachingNamespaceResolver class contains 
> excessive synchronization causing monitor contention that reduces performance.
> In JCR-685 there's a proposed patch that replaces synchronization with a 
> read-write lock that would allow concurrent read access to the name cache.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
https://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to