org.curjent.impl.agent
Class ProxyCache

java.lang.Object
  extended by org.curjent.impl.agent.ProxyCache

final class ProxyCache
extends Object

Cache for generated proxy classes. WeakReference is used to ensure proxy classes and related objects, such as the ClassLoader, are eligible for garbage collection.

The cache uses a hierarchical structure. The top-level key is the proxy's ClassLoader. Otherwise identical proxies are distinct if they were loaded by different class loaders. The next level is a synthetic key created to uniquely identify the proxy based on its interfaces and task type (see getKey(String[], String)). The final level is the cached value. This is the ProxyInfo used by ProxyFactory to create new proxy instances.

This class is thread-safe.


Field Summary
private  Map<ClassLoader,ConcurrentMap<String,Reference<ProxyInfo>>> cache
          Maps class loaders and proxy keys to cached ProxyInfo instances.
private  Lock lock
          Lock for accessing the top-level map.
 
Constructor Summary
ProxyCache()
           
 
Method Summary
(package private)  ProxyInfo get(ClassLoader classLoader, String proxyKey)
          Returns the cached proxy info for the given class loader and key.
(package private) static String getKey(String[] interfaceNames, String taskName)
          Generates a unique caching key for the agent's interfaces and task type.
(package private)  ProxyInfo put(ClassLoader classLoader, String proxyKey, ProxyInfo proxyInfo)
          Caches a proxy's info.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

cache

private final Map<ClassLoader,ConcurrentMap<String,Reference<ProxyInfo>>> cache
Maps class loaders and proxy keys to cached ProxyInfo instances.

See Also:
getKey(String[], String)

lock

private final Lock lock
Lock for accessing the top-level map. The second-level map uses a ConcurrentMap for thread safety.

Constructor Detail

ProxyCache

ProxyCache()
Method Detail

getKey

static String getKey(String[] interfaceNames,
                     String taskName)
Generates a unique caching key for the agent's interfaces and task type.


get

ProxyInfo get(ClassLoader classLoader,
              String proxyKey)
Returns the cached proxy info for the given class loader and key. Returns null if not found.


put

ProxyInfo put(ClassLoader classLoader,
              String proxyKey,
              ProxyInfo proxyInfo)
Caches a proxy's info. Concurrent creation of duplicate proxies is not prevented. This race condition is expected to be rare. Instead, the first proxy cached is used. Duplicates are orphaned. This method returns the first proxy info cached. This may or may not be the same as the given proxy info.

This algorithm avoids having to add a placeholder. Using a placeholder algorithm would add more complexity. Thread waiting and notification would have to be implemented. And the solution and its use would have to be carefully implemented by multiple classes to handle and recover from errors.



Copyright 2009-2011 Tom Landon
Apache License 2.0