Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kaspernielsen/540aacaf0581e7be80b0ebe3348f4a24 to your computer and use it in GitHub Desktop.
Save kaspernielsen/540aacaf0581e7be80b0ebe3348f4a24 to your computer and use it in GitHub Desktop.
LookupValue
/**
* Lazily associate a computed value with a lookup object much like {@link ClassValue} but for {@link Lookup} objects.
*/
public abstract class LookupValue<T> {
/** The cache of values. */
private final ClassValue<ConcurrentHashMap<Integer, T>> LOOKUP_CACHE = new ClassValue<>() {
/** {@inheritDoc} */
@Override
protected ConcurrentHashMap<Integer, T> computeValue(Class<?> type) {
return new ConcurrentHashMap<Integer, T>(1);
}
};
/**
* Computes the given lookup objects's derived value for this {@code LookupValue}.
* <p>
* This method will be invoked within the first thread that accesses the value with the {@link #get(Lookup) get} method.
* <p>
* If this method throws an exception, the corresponding call to {@code get} will terminate abnormally with that
* exception, and no lookup value will be recorded.
*
* @param lookup
* the lookup object for which a value must be computed
* @return the newly computed value associated with this {@code LookupValue}, for the given lookup object
*/
protected abstract T computeValue(MethodHandles.Lookup lookup);
/**
* Returns the value for the given lookup object. If no value has yet been computed, it is obtained by an invocation of
* the {@link #computeValue computeValue} method.
*
* @param lookup
* the lookup object
* @return the value for the given lookup object
*/
public final T get(MethodHandles.Lookup lookup) {
ConcurrentHashMap<Integer, T> chm = LOOKUP_CACHE.get(lookup.lookupClass());
Integer lookupMode = Integer.valueOf(lookup.lookupModes());
// we could just to chm.computeIfAbsent(..) but thats not garbage free
T value = chm.get(lookupMode);
if (value == null) {
value = chm.computeIfAbsent(lookupMode, ignore -> computeValue(lookup));
}
return value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment