package resa.util;
import redis.clients.jedis.Jedis;
import java.io.Closeable;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
/**
* This class is not thread-safe
* Created by ding on 14-5-29.
*/
public class RedisQueueIterable implements Iterable<String>, Closeable {
private String host;
private int port;
private String queue;
private Jedis jedis;
private final long end;
private final long start;
private final int bufferSize = 500;
public RedisQueueIterable(String host, int port, String queue) {
this(host, port, queue, Long.MAX_VALUE);
}
public RedisQueueIterable(String host, int port, String queue, long maxCount) {
this(host, port, queue, 0, maxCount);
}
public RedisQueueIterable(String host, int port, String queue, long start, long maxCount) {
this.host = host;
this.port = port;
this.queue = queue;
this.end = maxCount == Long.MAX_VALUE ? Long.MAX_VALUE : start + maxCount;
this.start = start;
}
private synchronized String[] fetchNextRange(long from) {
if (from < end) {
long bound = Math.min(end, from + bufferSize) - 1;
try {
List<String> nextRange = getJedis().lrange(queue, from, bound);
if (!nextRange.isEmpty()) {
return nextRange.toArray(new String[nextRange.size()]);
}
} catch (Exception e) {
}
}
return null;
}
@Override
public void close() throws IOException {
disconnect();
}
private class DataIter implements Iterator<String> {
private long count = 0;
private String[] cache = null;
private int pos = 0;
@Override
public boolean hasNext() {
if (cache == null || pos == cache.length) {
cache = fetchNextRange(start + count);
if (cache == null) {
return false;
}
pos = 0;
}
return true;
}
@Override
public String next() {
count++;
return cache[pos++];
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
private Jedis getJedis() {
if (jedis != null) {
return jedis;
}
//try connect to redis server
try {
jedis = new Jedis(host, port);
} catch (Exception e) {
}
return jedis;
}
private void disconnect() {
if (jedis != null) {
try {
jedis.disconnect();
} catch (Exception e) {
}
jedis = null;
}
}
@Override
public Iterator<String> iterator() {
return new DataIter();
}
}