From ad5385aa9864e0e60a1e2513e18427da88aa0a00 Mon Sep 17 00:00:00 2001 From: Nikita Date: Fri, 17 Jul 2015 15:46:40 +0300 Subject: [PATCH] RSetAsync interface added. #186 --- src/main/java/org/redisson/RedissonSet.java | 116 +++++++++++++----- .../client/protocol/RedisCommands.java | 5 +- .../BooleanAmountReplayConvertor.java | 26 ++++ .../BooleanNumberReplayConvertor.java | 26 ++++ .../org/redisson/core/RCollectionAsync.java | 5 +- src/main/java/org/redisson/core/RSet.java | 8 +- .../java/org/redisson/core/RSetAsync.java | 27 ++++ .../java/org/redisson/RedissonSetTest.java | 12 +- 8 files changed, 179 insertions(+), 46 deletions(-) create mode 100644 src/main/java/org/redisson/client/protocol/convertor/BooleanAmountReplayConvertor.java create mode 100644 src/main/java/org/redisson/client/protocol/convertor/BooleanNumberReplayConvertor.java create mode 100644 src/main/java/org/redisson/core/RSetAsync.java diff --git a/src/main/java/org/redisson/RedissonSet.java b/src/main/java/org/redisson/RedissonSet.java index df5296d43..f499fc099 100644 --- a/src/main/java/org/redisson/RedissonSet.java +++ b/src/main/java/org/redisson/RedissonSet.java @@ -17,11 +17,14 @@ package org.redisson; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; +import org.redisson.client.protocol.RedisCommand; import org.redisson.client.protocol.RedisCommands; +import org.redisson.client.protocol.convertor.BooleanReplayConvertor; import org.redisson.client.protocol.decoder.ListScanResult; import org.redisson.connection.ConnectionManager; import org.redisson.core.RSet; @@ -43,7 +46,12 @@ public class RedissonSet extends RedissonExpirable implements RSet { @Override public int size() { - return ((Long)connectionManager.read(getName(), RedisCommands.SCARD, getName())).intValue(); + return connectionManager.get(sizeAsync()); + } + + @Override + public Future sizeAsync() { + return connectionManager.readAsync(getName(), RedisCommands.SCARD, getName()); } @Override @@ -53,7 +61,12 @@ public class RedissonSet extends RedissonExpirable implements RSet { @Override public boolean contains(Object o) { - return connectionManager.read(getName(), RedisCommands.SISMEMBER, getName(), o); + return connectionManager.get(containsAsync(o)); + } + + @Override + public Future containsAsync(Object o) { + return connectionManager.readAsync(getName(), RedisCommands.SISMEMBER, getName(), o); } private ListScanResult scanIterator(long startPos) { @@ -111,15 +124,20 @@ public class RedissonSet extends RedissonExpirable implements RSet { }; } + @Override + public Future> readAllAsync() { + return connectionManager.readAsync(getName(), RedisCommands.SMEMBERS, getName()); + } + @Override public Object[] toArray() { - List res = connectionManager.read(getName(), RedisCommands.SMEMBERS, getName()); + List res = (List) connectionManager.get(readAllAsync()); return res.toArray(); } @Override public T[] toArray(T[] a) { - List res = connectionManager.read(getName(), RedisCommands.SMEMBERS, getName()); + List res = (List) connectionManager.get(readAllAsync()); return res.toArray(a); } @@ -134,8 +152,8 @@ public class RedissonSet extends RedissonExpirable implements RSet { } @Override - public Future removeAsync(V e) { - return connectionManager.writeAsync(getName(), RedisCommands.SREM_SINGLE, getName(), e); + public Future removeAsync(Object o) { + return connectionManager.writeAsync(getName(), RedisCommands.SREM_SINGLE, getName(), o); } @Override @@ -145,49 +163,85 @@ public class RedissonSet extends RedissonExpirable implements RSet { @Override public boolean containsAll(Collection c) { - for (Object object : c) { - if (!contains(object)) { - return false; - } - } - return true; + return connectionManager.get(containsAllAsync(c)); } @Override - public boolean addAll(final Collection c) { + public Future containsAllAsync(Collection c) { + return connectionManager.evalReadAsync(getName(), new RedisCommand("EVAL", new BooleanReplayConvertor(), 4), + "local s = redis.call('smembers', KEYS[1]);" + + "for i = 0, table.getn(s), 1 do " + + "for j = 0, table.getn(ARGV), 1 do " + + "if ARGV[j] == s[i] " + + "then table.remove(ARGV, j) end " + + "end; " + + "end;" + + "return table.getn(ARGV) == 0; ", + Collections.singletonList(getName()), c.toArray()); + } + + @Override + public boolean addAll(Collection c) { if (c.isEmpty()) { return false; } + return connectionManager.get(addAllAsync(c)); + } + + @Override + public Future addAllAsync(Collection c) { List args = new ArrayList(c.size() + 1); args.add(getName()); args.addAll(c); - Long res = connectionManager.write(getName(), RedisCommands.SADD, args.toArray()); - return res > 0; + return connectionManager.writeAsync(getName(), RedisCommands.SADD, args.toArray()); } @Override public boolean retainAll(Collection c) { - List toRemove = new ArrayList(); - for (V object : this) { - if (!c.contains(object)) { - toRemove.add(object); - } - } - return removeAll(toRemove); + return connectionManager.get(retainAllAsync(c)); } @Override - public boolean removeAll(final Collection c) { - if (c.isEmpty()) { - return false; - } + public Future retainAllAsync(Collection c) { + return connectionManager.evalWriteAsync(getName(), new RedisCommand("EVAL", new BooleanReplayConvertor(), 4), + "local changed = false " + + "local s = redis.call('smembers', KEYS[1]) " + + "local i = 0 " + + "while i <= table.getn(s) do " + + "local element = s[i] " + + "local isInAgrs = false " + + "for j = 0, table.getn(ARGV), 1 do " + + "if ARGV[j] == element then " + + "isInAgrs = true " + + "break " + + "end " + + "end " + + "if isInAgrs == false then " + + "redis.call('SREM', KEYS[1], element) " + + "changed = true " + + "end " + + "i = i + 1 " + + "end " + + "return changed ", + Collections.singletonList(getName()), c.toArray()); + } - List args = new ArrayList(c.size() + 1); - args.add(getName()); - args.addAll(c); - Long res = connectionManager.write(getName(), RedisCommands.SREM, args.toArray()); - return res > 0; + @Override + public Future removeAllAsync(Collection c) { + return connectionManager.evalWriteAsync(getName(), new RedisCommand("EVAL", new BooleanReplayConvertor(), 4), + "local v = false " + + "for i = 0, table.getn(ARGV), 1 do " + + "if redis.call('srem', KEYS[1], ARGV[i]) == 1 " + + "then v = true end " + +"end " + + "return v ", + Collections.singletonList(getName()), c.toArray()); + } + + @Override + public boolean removeAll(Collection c) { + return connectionManager.get(removeAllAsync(c)); } @Override diff --git a/src/main/java/org/redisson/client/protocol/RedisCommands.java b/src/main/java/org/redisson/client/protocol/RedisCommands.java index 0f49bbbe0..82937c232 100644 --- a/src/main/java/org/redisson/client/protocol/RedisCommands.java +++ b/src/main/java/org/redisson/client/protocol/RedisCommands.java @@ -20,6 +20,7 @@ import java.util.Map; import java.util.Set; import org.redisson.client.protocol.RedisCommand.ValueType; +import org.redisson.client.protocol.convertor.BooleanAmountReplayConvertor; import org.redisson.client.protocol.convertor.BooleanReplayConvertor; import org.redisson.client.protocol.convertor.IntegerReplayConvertor; import org.redisson.client.protocol.convertor.VoidReplayConvertor; @@ -46,13 +47,13 @@ public interface RedisCommands { RedisCommand> EXEC = new RedisCommand>("EXEC", new ObjectListReplayDecoder()); RedisCommand SREM = new RedisCommand("SREM", 2, ValueType.OBJECTS); - RedisCommand SADD = new RedisCommand("SADD", 2, ValueType.OBJECTS); + RedisCommand SADD = new RedisCommand("SADD", new BooleanAmountReplayConvertor(), 2, ValueType.OBJECTS); RedisCommand SADD_SINGLE = new RedisCommand("SADD", new BooleanReplayConvertor(), 2); RedisCommand SREM_SINGLE = new RedisCommand("SREM", new BooleanReplayConvertor(), 2); RedisCommand> SMEMBERS = new RedisCommand>("SMEMBERS", new ObjectListReplayDecoder()); RedisCommand> SSCAN = new RedisCommand>("SSCAN", new NestedMultiDecoder(new ObjectListReplayDecoder(), new ListScanResultReplayDecoder()), ValueType.MAP); RedisCommand SISMEMBER = new RedisCommand("SISMEMBER", new BooleanReplayConvertor(), 2); - RedisStrictCommand SCARD = new RedisStrictCommand("SCARD"); + RedisStrictCommand SCARD = new RedisStrictCommand("SCARD", new IntegerReplayConvertor()); RedisCommand LSET = new RedisCommand("LSET", new VoidReplayConvertor(), 3); RedisCommand LPOP = new RedisCommand("LPOP"); diff --git a/src/main/java/org/redisson/client/protocol/convertor/BooleanAmountReplayConvertor.java b/src/main/java/org/redisson/client/protocol/convertor/BooleanAmountReplayConvertor.java new file mode 100644 index 000000000..b3d11733c --- /dev/null +++ b/src/main/java/org/redisson/client/protocol/convertor/BooleanAmountReplayConvertor.java @@ -0,0 +1,26 @@ +/** + * Copyright 2014 Nikita Koksharov, Nickolay Borbit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.redisson.client.protocol.convertor; + +public class BooleanAmountReplayConvertor extends SingleConvertor { + + @Override + public Boolean convert(Object obj) { + return (Long)obj > 0; + } + + +} diff --git a/src/main/java/org/redisson/client/protocol/convertor/BooleanNumberReplayConvertor.java b/src/main/java/org/redisson/client/protocol/convertor/BooleanNumberReplayConvertor.java new file mode 100644 index 000000000..916673e05 --- /dev/null +++ b/src/main/java/org/redisson/client/protocol/convertor/BooleanNumberReplayConvertor.java @@ -0,0 +1,26 @@ +/** + * Copyright 2014 Nikita Koksharov, Nickolay Borbit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.redisson.client.protocol.convertor; + +public class BooleanNumberReplayConvertor extends SingleConvertor { + + @Override + public Boolean convert(Object obj) { + return (Long)obj != -1; + } + + +} diff --git a/src/main/java/org/redisson/core/RCollectionAsync.java b/src/main/java/org/redisson/core/RCollectionAsync.java index 8d4137d70..fa63a019b 100644 --- a/src/main/java/org/redisson/core/RCollectionAsync.java +++ b/src/main/java/org/redisson/core/RCollectionAsync.java @@ -1,7 +1,6 @@ package org.redisson.core; import java.util.Collection; -import java.util.List; import io.netty.util.concurrent.Future; @@ -11,11 +10,13 @@ public interface RCollectionAsync extends RExpirableAsync { Future removeAllAsync(Collection c); + Future containsAsync(Object o); + Future containsAllAsync(Collection c); Future removeAsync(Object o); - Future> readAllAsync(); + Future> readAllAsync(); Future sizeAsync(); diff --git a/src/main/java/org/redisson/core/RSet.java b/src/main/java/org/redisson/core/RSet.java index 9fef5766f..6725f80fa 100644 --- a/src/main/java/org/redisson/core/RSet.java +++ b/src/main/java/org/redisson/core/RSet.java @@ -15,8 +15,6 @@ */ package org.redisson.core; -import io.netty.util.concurrent.Future; - import java.util.Set; /** @@ -26,10 +24,6 @@ import java.util.Set; * * @param value */ -public interface RSet extends Set, RExpirable { +public interface RSet extends Set, RExpirable, RSetAsync { - Future addAsync(V value); - - Future removeAsync(V value); - } diff --git a/src/main/java/org/redisson/core/RSetAsync.java b/src/main/java/org/redisson/core/RSetAsync.java new file mode 100644 index 000000000..bf555286d --- /dev/null +++ b/src/main/java/org/redisson/core/RSetAsync.java @@ -0,0 +1,27 @@ +/** + * Copyright 2014 Nikita Koksharov, Nickolay Borbit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.redisson.core; + +/** + * Async set functions + * + * @author Nikita Koksharov + * + * @param value + */ +public interface RSetAsync extends RCollectionAsync { + +} diff --git a/src/test/java/org/redisson/RedissonSetTest.java b/src/test/java/org/redisson/RedissonSetTest.java index bd2154aa8..e360f9e69 100644 --- a/src/test/java/org/redisson/RedissonSetTest.java +++ b/src/test/java/org/redisson/RedissonSetTest.java @@ -1,9 +1,11 @@ package org.redisson; -import io.netty.util.concurrent.Future; - import java.io.Serializable; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; import java.util.concurrent.ExecutionException; import org.hamcrest.MatcherAssert; @@ -11,7 +13,8 @@ import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Test; import org.redisson.core.RSet; -import org.redisson.core.RSortedSet; + +import io.netty.util.concurrent.Future; public class RedissonSetTest extends BaseTest { @@ -191,6 +194,7 @@ public class RedissonSetTest extends BaseTest { set.add(i); } + Assert.assertTrue(set.containsAll(Collections.emptyList())); Assert.assertTrue(set.containsAll(Arrays.asList(30, 11))); Assert.assertFalse(set.containsAll(Arrays.asList(30, 711, 11))); }