}
List<String> memIdsRet = new LinkedList<String>();
Set <String> memIds = null;
boolean brokenJedis = false;
ShardedJedis jedis = null;
try {
jedis = getResource();
String key = queueUrl + "-" + shard + "-Q";
long llen = jedis.zcount(key, System.currentTimeMillis() - retention * 1000L, System.currentTimeMillis());
if (llen == 0L) {
return Collections.emptyList();
}
//if no previousReceiptHandle and no nextReceiptHandle, just retrieve from beginning
if (previousReceiptHandle == null && nextReceiptHandle == null) {
memIds = jedis.zrangeByScore(key, System.currentTimeMillis() - retention * 1000L, System.currentTimeMillis(), 0, num);
if (memIds != null){
memIdsRet = new ArrayList<String>(memIds);
}
}
//else find the score for previous receipt,
// if not exist, same as no previous receipt
// else use zrangeByScore with limit
else if (previousReceiptHandle != null) {
Double previousScore = jedis.zscore(key, previousReceiptHandle);
if (previousScore == null) {
memIds = jedis.zrangeByScore(key, System.currentTimeMillis() - retention * 1000L, System.currentTimeMillis(), 0, num);
if (memIds != null){
memIdsRet = new ArrayList<String>(memIds);
}
} else {
long startTime = previousScore.longValue();
if (startTime < System.currentTimeMillis() - retention * 1000L) {
startTime = System.currentTimeMillis() - retention * 1000L;
}
int retCount = 0;
int i = 0;
boolean includeSet = (previousReceiptHandle == null) ? true : false;
while (retCount < num && i < llen) {
memIds = jedis.zrangeByScore(key, startTime, System.currentTimeMillis(), i, num);
if (memIds.size() == 0) {
break; // done
}
i += num; // next time, exclude the last one in this set
for (String memId : memIds) {
if (!includeSet) {
if (memId.equals(previousReceiptHandle)) {
includeSet = true;
//skip over this one since it was the last el of the last call
}
} else {
memIdsRet.add(memId);
retCount++;
if (retCount >= num) {
break; //done
}
}
}
}
}
} else { //this means previousReceiptHandle == null and nextReceiptHandle != null. Retrieve id backward
//return result will exclude the nextReceiptHandle
//retrieve nextReceiptHandle, get index. if not exist, retrieve from beginning.
Long endRank = jedis.zrank(key, nextReceiptHandle);
if (endRank == null) {
memIds = jedis.zrangeByScore(key, System.currentTimeMillis() - retention * 1000L, System.currentTimeMillis(), 0, num);
if (memIds != null){
memIdsRet = new ArrayList<String>(memIds);
}
}
//if index exist, retrieve based on index. When get result, remove expired id
else {
long startIndex = endRank - num;
if (startIndex < 0 ){
startIndex = 0;
}
Set <Tuple> memIdWithScores = jedis.zrangeWithScores(key, startIndex, endRank);
long expiredTime = System.currentTimeMillis() - retention * 1000L;
for (Tuple t: memIdWithScores) {
if (t.getScore() < expiredTime || t.getElement().equals(nextReceiptHandle)) {
continue;
} else {