From c9ac67ea7ecebc69128196ca746cd42d5f98a9b2 Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 25 Apr 2016 17:12:55 +0300 Subject: [PATCH] Few iterator improvements --- .../org/redisson/RedissonBaseIterator.java | 87 ++++++++++++++----- .../org/redisson/RedissonBaseMapIterator.java | 5 ++ src/main/java/org/redisson/RedissonSet.java | 33 +++++-- .../MasterSlaveConnectionManager.java | 4 +- 4 files changed, 99 insertions(+), 30 deletions(-) diff --git a/src/main/java/org/redisson/RedissonBaseIterator.java b/src/main/java/org/redisson/RedissonBaseIterator.java index ab1eaa0449b..3f6c62c7a02 100644 --- a/src/main/java/org/redisson/RedissonBaseIterator.java +++ b/src/main/java/org/redisson/RedissonBaseIterator.java @@ -16,6 +16,7 @@ package org.redisson; import java.net.InetSocketAddress; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; @@ -25,42 +26,87 @@ abstract class RedissonBaseIterator implements Iterator { private List firstValues; - private Iterator iter; - private InetSocketAddress client; - private long nextIterPos; - private long startPos = -1; + private List lastValues; + private Iterator lastIter; + protected long nextIterPos; + protected InetSocketAddress client; + private boolean finished; private boolean currentElementRemoved; private boolean removeExecuted; private V value; @Override public boolean hasNext() { - if (iter == null || !iter.hasNext()) { - if (nextIterPos == -1) { - return false; + if (lastIter == null || !lastIter.hasNext()) { + if (finished) { + + currentElementRemoved = false; + removeExecuted = false; + client = null; + firstValues = null; + lastValues = null; + nextIterPos = 0; + + if (!tryAgain()) { + return false; + } + finished = false; } long prevIterPos; do { prevIterPos = nextIterPos; ListScanResult res = iterator(client, nextIterPos); + lastValues = new ArrayList(res.getValues()); client = res.getRedisClient(); - if (startPos == -1) { - startPos = res.getPos(); - } + if (nextIterPos == 0 && firstValues == null) { - firstValues = res.getValues(); - } else if (res.getValues().equals(firstValues) && res.getPos() == startPos) { - return false; + firstValues = lastValues; + lastValues = null; + if (firstValues.isEmpty() && tryAgain()) { + client = null; + firstValues = null; + nextIterPos = 0; + prevIterPos = -1; + } + } else { + if (firstValues.isEmpty()) { + firstValues = lastValues; + lastValues = null; + if (firstValues.isEmpty() && tryAgain()) { + client = null; + firstValues = null; + nextIterPos = 0; + prevIterPos = -1; + continue; + } + } else if (lastValues.removeAll(firstValues)) { + currentElementRemoved = false; + removeExecuted = false; + client = null; + firstValues = null; + lastValues = null; + nextIterPos = 0; + prevIterPos = -1; + if (tryAgain()) { + continue; + } + finished = true; + return false; + } } - iter = res.getValues().iterator(); + lastIter = res.getValues().iterator(); nextIterPos = res.getPos(); - } while (!iter.hasNext() && nextIterPos != prevIterPos); + } while (!lastIter.hasNext() && nextIterPos != prevIterPos); if (prevIterPos == nextIterPos && !removeExecuted) { - nextIterPos = -1; + finished = true; } } - return iter.hasNext(); + return lastIter.hasNext(); + } + + protected boolean tryAgain() { + return false; } abstract ListScanResult iterator(InetSocketAddress client, long nextIterPos); @@ -71,7 +117,7 @@ public V next() { throw new NoSuchElementException("No such element"); } - value = iter.next(); + value = lastIter.next(); currentElementRemoved = false; return value; } @@ -81,11 +127,12 @@ public void remove() { if (currentElementRemoved) { throw new IllegalStateException("Element been already deleted"); } - if (iter == null) { + if (lastIter == null) { throw new IllegalStateException(); } - iter.remove(); + firstValues.remove(value); + lastIter.remove(); remove(value); currentElementRemoved = true; removeExecuted = true; diff --git a/src/main/java/org/redisson/RedissonBaseMapIterator.java b/src/main/java/org/redisson/RedissonBaseMapIterator.java index 2af67769b61..b3124679586 100644 --- a/src/main/java/org/redisson/RedissonBaseMapIterator.java +++ b/src/main/java/org/redisson/RedissonBaseMapIterator.java @@ -75,6 +75,7 @@ public boolean hasNext() { if (firstValues.isEmpty() && tryAgain()) { client = null; firstValues = null; + nextIterPos = 0; prevIterPos = -1; } } else { @@ -82,6 +83,10 @@ public boolean hasNext() { firstValues = lastValues; lastValues = null; if (firstValues.isEmpty() && tryAgain()) { + client = null; + firstValues = null; + nextIterPos = 0; + prevIterPos = -1; continue; } } else if (lastValues.keySet().removeAll(firstValues.keySet())) { diff --git a/src/main/java/org/redisson/RedissonSet.java b/src/main/java/org/redisson/RedissonSet.java index a7466e24bcc..c0db7dea711 100644 --- a/src/main/java/org/redisson/RedissonSet.java +++ b/src/main/java/org/redisson/RedissonSet.java @@ -80,8 +80,8 @@ protected String getName(Object o) { return getName(); } - private ListScanResult scanIterator(InetSocketAddress client, long startPos) { - Future> f = commandExecutor.readAsync(client, getName(), codec, RedisCommands.SSCAN, getName(), startPos); + ListScanResult scanIterator(String name, InetSocketAddress client, long startPos) { + Future> f = commandExecutor.readAsync(client, name, codec, RedisCommands.SSCAN, name, startPos); return get(f); } @@ -91,7 +91,7 @@ public Iterator iterator() { @Override ListScanResult iterator(InetSocketAddress client, long nextIterPos) { - return scanIterator(client, nextIterPos); + return scanIterator(getName(), client, nextIterPos); } @Override @@ -185,10 +185,6 @@ public Future containsAllAsync(Collection c) { @Override public boolean addAll(Collection c) { - if (c.isEmpty()) { - return false; - } - return get(addAllAsync(c)); } @@ -229,7 +225,11 @@ public Future removeAllAsync(Collection c) { return newSucceededFuture(false); } - return commandExecutor.writeAsync(getName(), codec, RedisCommands.SREM_SINGLE, getName(), c.toArray()); + List args = new ArrayList(c.size() + 1); + args.add(getName()); + args.addAll(c); + + return commandExecutor.writeAsync(getName(), codec, RedisCommands.SREM_SINGLE, c.toArray()); } @Override @@ -268,4 +268,21 @@ public void clear() { delete(); } + @Override + public String toString() { + Iterator it = iterator(); + if (! it.hasNext()) + return "[]"; + + StringBuilder sb = new StringBuilder(); + sb.append('['); + for (;;) { + V e = it.next(); + sb.append(e == this ? "(this Collection)" : e); + if (! it.hasNext()) + return sb.append(']').toString(); + sb.append(',').append(' '); + } + } + } diff --git a/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java b/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java index 63f8e175ffc..abdb48f9894 100644 --- a/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java +++ b/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java @@ -99,7 +99,7 @@ public boolean cancel() { } }; - protected static final int MAX_SLOT = 16384; + public static final int MAX_SLOT = 16384; protected final ClusterSlotRange singleSlotRange = new ClusterSlotRange(0, MAX_SLOT); @@ -121,7 +121,7 @@ public boolean cancel() { protected boolean isClusterMode; - protected final Map entries = PlatformDependent.newConcurrentHashMap(); + private final Map entries = PlatformDependent.newConcurrentHashMap(); private final Promise shutdownPromise;