package proj.zoie.api.impl;
import java.util.Map.Entry;
import java.util.WeakHashMap;
import proj.zoie.api.ZoieMultiReader;
/**
* This class holds the ZoieContext for each thread. Any child thread inherits
* the context from the parent. The inherited context is a clone of the parent
* context so that forthcoming changes to the contexts of the parent and the
* children are independent of each other.
* @author "Xiaoyang Gu<xgu@linkedin.com>"
*
*/
public class ZoieContext {
private static InheritableThreadLocal<ZoieContext> _context = new InheritableThreadLocal<ZoieContext>() {
@Override
protected ZoieContext childValue(ZoieContext parentValue) {
return parentValue.clone();
}
@Override
protected ZoieContext initialValue() {
return new ZoieContext();
}
};
// use weakHashMap so that if a reader is no longer used, the map entry goes
// away.
protected WeakHashMap<ZoieMultiReader<?>, ZoieReaderContext> _zoieContextMap = new WeakHashMap<ZoieMultiReader<?>, ZoieReaderContext>();
public static ZoieContext getContext() {
return _context.get();
}
/**
* Set the threadlocal ZoieContext. It always clone it so that the threads
* won't interfere with each other.
*
* @param context
*/
public static void setContext(ZoieContext context) {
_context.set(context.clone());
}
/**
* Get the context of the given reader for the calling thread.
*
* @param reader
*/
public synchronized ZoieReaderContext getReaderContext(ZoieMultiReader<?> reader) {
ZoieReaderContext ctx = _zoieContextMap.get(reader);
if (ctx == null) {
ctx = new ZoieReaderContext();
_zoieContextMap.put(reader, ctx);
}
return ctx;
}
/**
* clone the ZoieContext so that the internal hashmap is deep-copied to the
* extend that in the clone, the ZoieReaderContexts are clones of the
* original. Note that the internals of ZoieReaderContexts are shallow copies.
*
* @see java.lang.Object#clone()
*/
@Override
protected ZoieContext clone() {
ZoieContext ctx = new ZoieContext();
for (Entry<ZoieMultiReader<?>, ZoieReaderContext> pair : _zoieContextMap.entrySet()) {
ctx._zoieContextMap.put(pair.getKey(), pair.getValue().clone());
}
return ctx;
}
public synchronized void clear() {
_zoieContextMap.clear();
}
}