package edu.uw.zookeeper.data;
import static com.google.common.base.Preconditions.*;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import net.engio.mbassy.common.StrongConcurrentSet;
import edu.uw.zookeeper.client.ClientExecutor;
import edu.uw.zookeeper.data.SimpleLabelTrie;
import edu.uw.zookeeper.data.NameTrie;
import edu.uw.zookeeper.protocol.Operation;
import edu.uw.zookeeper.protocol.SessionListener;
import edu.uw.zookeeper.protocol.proto.Records;
/**
* Use lock() when accessing cache()
*/
public class LockableZNodeCache<E extends AbstractNameTrie.SimpleNode<E> & LockableZNodeCache.CacheNode<E,?>, I extends Operation.Request, O extends Operation.ProtocolResponse<?>>
extends ZNodeCache<E,I,O> {
public static <I extends Operation.Request,O extends Operation.ProtocolResponse<?>> LockableZNodeCache<SimpleCacheNode,I,O> newInstance(
ClientExecutor<? super I,O,SessionListener> client) {
return newInstance(client, SimpleCacheNode.root());
}
public static <E extends AbstractNameTrie.SimpleNode<E> & LockableZNodeCache.CacheNode<E,?>, I extends Operation.Request,O extends Operation.ProtocolResponse<?>> LockableZNodeCache<E,I,O> newInstance(
ClientExecutor<? super I,O,SessionListener> client, E root) {
return new LockableZNodeCache<E,I,O>(new ReentrantReadWriteLock(true), client, new CacheEvents(new StrongConcurrentSet<CacheListener>()), SimpleLabelTrie.forRoot(root));
}
protected final ReentrantReadWriteLock lock;
protected LockableZNodeCache(
ReentrantReadWriteLock lock,
ClientExecutor<? super I, O, SessionListener> client,
CacheEvents events,
NameTrie<E> trie) {
super(client, events, trie);
this.lock = checkNotNull(lock);
}
public ReentrantReadWriteLock lock() {
return lock;
}
@Override
protected void handleResult(Records.Request request, Operation.ProtocolResponse<?> result) {
lock.writeLock().lock();
try {
super.handleResult(request, result);
} finally {
lock.writeLock().unlock();
}
}
}