package edu.uw.zookeeper.client.random;
import java.util.List;
import java.util.Random;
import java.util.Set;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import edu.uw.zookeeper.data.NodeWatchEvent;
import edu.uw.zookeeper.data.ZNodeCache;
import edu.uw.zookeeper.data.LockableZNodeCache;
import edu.uw.zookeeper.common.Generator;
import edu.uw.zookeeper.data.ZNodePath;
public class CachedPaths implements Generator<ZNodePath>, ZNodeCache.CacheListener {
public static CachedPaths fromCache(LockableZNodeCache<?,?,?> cache, Random random) {
CachedPaths instance = new CachedPaths(random, ImmutableList.<ZNodePath>of());
cache.events().subscribe(instance);
cache.lock().readLock().lock();
try {
for (ZNodeCache.CacheNode<?,?> e: cache.cache()) {
instance.add(e.path());
}
} finally {
cache.lock().readLock().unlock();
}
return instance;
}
protected final Random random;
protected final List<ZNodePath> elements;
protected CachedPaths(Random random, Iterable<ZNodePath> elements) {
this.random = random;
this.elements = Lists.newArrayList(elements);
}
public synchronized boolean add(ZNodePath element) {
if (! elements.contains(element)) {
return elements.add(element);
} else {
return false;
}
}
public synchronized boolean remove(ZNodePath element) {
return elements.remove(element);
}
@Override
public synchronized ZNodePath next() {
int size = elements.size();
if (size == 0) {
return null;
} else {
int index = random.nextInt(size);
return elements.get(index);
}
}
@Override
public void handleCacheEvent(Set<NodeWatchEvent> events) {
for (NodeWatchEvent event: events) {
switch (event.getEventType()) {
case NodeCreated:
add(event.getPath());
break;
case NodeDeleted:
remove(event.getPath());
break;
default:
break;
}
}
}
}