|
|
|
@ -19,24 +19,20 @@ import java.util.ArrayList;
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import java.util.Collection;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Set;
|
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
|
|
import org.reactivestreams.Publisher;
|
|
|
|
|
import org.redisson.RedissonSetCache;
|
|
|
|
|
import org.redisson.ScanIterator;
|
|
|
|
|
import org.redisson.api.RFuture;
|
|
|
|
|
import org.redisson.api.RSetCacheAsync;
|
|
|
|
|
import org.redisson.api.RSetCacheReactive;
|
|
|
|
|
import org.redisson.api.RSetCache;
|
|
|
|
|
import org.redisson.client.RedisClient;
|
|
|
|
|
import org.redisson.client.codec.Codec;
|
|
|
|
|
import org.redisson.client.protocol.RedisCommands;
|
|
|
|
|
import org.redisson.client.protocol.decoder.ListScanResult;
|
|
|
|
|
import org.redisson.command.CommandReactiveExecutor;
|
|
|
|
|
import org.redisson.eviction.EvictionScheduler;
|
|
|
|
|
|
|
|
|
|
import io.netty.buffer.ByteBuf;
|
|
|
|
|
import reactor.fn.Supplier;
|
|
|
|
|
import reactor.rx.Streams;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <p>Set-based cache with ability to set TTL for each entry via
|
|
|
|
@ -58,151 +54,54 @@ import reactor.fn.Supplier;
|
|
|
|
|
*
|
|
|
|
|
* @param <V> value
|
|
|
|
|
*/
|
|
|
|
|
public class RedissonSetCacheReactive<V> extends RedissonExpirableReactive implements RSetCacheReactive<V> {
|
|
|
|
|
public class RedissonSetCacheReactive<V> {
|
|
|
|
|
|
|
|
|
|
private final RSetCacheAsync<V> instance;
|
|
|
|
|
private final RSetCache<V> instance;
|
|
|
|
|
private final CommandReactiveExecutor commandExecutor;
|
|
|
|
|
|
|
|
|
|
public RedissonSetCacheReactive(EvictionScheduler evictionScheduler, CommandReactiveExecutor commandExecutor, String name) {
|
|
|
|
|
this(commandExecutor, name, new RedissonSetCache<V>(evictionScheduler, commandExecutor, name, null));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public RedissonSetCacheReactive(CommandReactiveExecutor commandExecutor, String name, RSetCacheAsync<V> instance) {
|
|
|
|
|
super(commandExecutor, name, instance);
|
|
|
|
|
this.instance = instance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public RedissonSetCacheReactive(Codec codec, EvictionScheduler evictionScheduler, CommandReactiveExecutor commandExecutor, String name) {
|
|
|
|
|
this(codec, commandExecutor, name, new RedissonSetCache<V>(codec, evictionScheduler, commandExecutor, name, null));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public RedissonSetCacheReactive(Codec codec, CommandReactiveExecutor commandExecutor, String name, RSetCacheAsync<V> instance) {
|
|
|
|
|
super(codec, commandExecutor, name, instance);
|
|
|
|
|
public RedissonSetCacheReactive(CommandReactiveExecutor commandExecutor, RSetCache<V> instance) {
|
|
|
|
|
this.commandExecutor = commandExecutor;
|
|
|
|
|
this.instance = instance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Publisher<Integer> size() {
|
|
|
|
|
return reactive(new Supplier<RFuture<Integer>>() {
|
|
|
|
|
@Override
|
|
|
|
|
public RFuture<Integer> get() {
|
|
|
|
|
return instance.sizeAsync();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Publisher<Boolean> contains(final Object o) {
|
|
|
|
|
return reactive(new Supplier<RFuture<Boolean>>() {
|
|
|
|
|
@Override
|
|
|
|
|
public RFuture<Boolean> get() {
|
|
|
|
|
return instance.containsAsync(o);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Publisher<V> iterator() {
|
|
|
|
|
return new SetReactiveIterator<V>() {
|
|
|
|
|
@Override
|
|
|
|
|
protected RFuture<ListScanResult<Object>> scanIterator(RedisClient client, long nextIterPos) {
|
|
|
|
|
return ((ScanIterator)instance).scanIteratorAsync(getName(), client, nextIterPos, null, 10);
|
|
|
|
|
return ((ScanIterator)instance).scanIteratorAsync(instance.getName(), client, nextIterPos, null, 10);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Publisher<Boolean> add(final V value, final long ttl, final TimeUnit unit) {
|
|
|
|
|
return reactive(new Supplier<RFuture<Boolean>>() {
|
|
|
|
|
@Override
|
|
|
|
|
public RFuture<Boolean> get() {
|
|
|
|
|
return instance.addAsync(value, ttl, unit);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Publisher<Integer> add(V value) {
|
|
|
|
|
long timeoutDate = 92233720368547758L;
|
|
|
|
|
return commandExecutor.evalWriteReactive(getName(), codec, RedisCommands.EVAL_INTEGER,
|
|
|
|
|
return commandExecutor.evalWriteReactive(instance.getName(), instance.getCodec(), RedisCommands.EVAL_INTEGER,
|
|
|
|
|
"local expireDateScore = redis.call('zscore', KEYS[1], ARGV[3]); "
|
|
|
|
|
+ "if expireDateScore ~= false and tonumber(expireDateScore) > tonumber(ARGV[1]) then "
|
|
|
|
|
+ "return 0;"
|
|
|
|
|
+ "end; " +
|
|
|
|
|
"redis.call('zadd', KEYS[1], ARGV[2], ARGV[3]); " +
|
|
|
|
|
"return 1; ",
|
|
|
|
|
Arrays.<Object>asList(getName()), System.currentTimeMillis(), timeoutDate, encode(value));
|
|
|
|
|
Arrays.<Object>asList(instance.getName()), System.currentTimeMillis(), timeoutDate, ((RedissonSetCache)instance).encode(value));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Publisher<Set<V>> readAll() {
|
|
|
|
|
return reactive(new Supplier<RFuture<Set<V>>>() {
|
|
|
|
|
@Override
|
|
|
|
|
public RFuture<Set<V>> get() {
|
|
|
|
|
return instance.readAllAsync();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Publisher<Boolean> remove(final Object o) {
|
|
|
|
|
return reactive(new Supplier<RFuture<Boolean>>() {
|
|
|
|
|
@Override
|
|
|
|
|
public RFuture<Boolean> get() {
|
|
|
|
|
return instance.removeAsync(o);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Publisher<Boolean> containsAll(final Collection<?> c) {
|
|
|
|
|
return reactive(new Supplier<RFuture<Boolean>>() {
|
|
|
|
|
@Override
|
|
|
|
|
public RFuture<Boolean> get() {
|
|
|
|
|
return instance.containsAllAsync(c);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Publisher<Integer> addAll(Collection<? extends V> c) {
|
|
|
|
|
if (c.isEmpty()) {
|
|
|
|
|
return newSucceeded(0);
|
|
|
|
|
return Streams.just(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long score = 92233720368547758L - System.currentTimeMillis();
|
|
|
|
|
List<Object> params = new ArrayList<Object>(c.size()*2 + 1);
|
|
|
|
|
params.add(getName());
|
|
|
|
|
params.add(instance.getName());
|
|
|
|
|
for (V value : c) {
|
|
|
|
|
ByteBuf objectState = encode(value);
|
|
|
|
|
ByteBuf objectState = ((RedissonSetCache)instance).encode(value);
|
|
|
|
|
params.add(score);
|
|
|
|
|
params.add(objectState);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return commandExecutor.writeReactive(getName(), codec, RedisCommands.ZADD_RAW, params.toArray());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Publisher<Boolean> retainAll(final Collection<?> c) {
|
|
|
|
|
return reactive(new Supplier<RFuture<Boolean>>() {
|
|
|
|
|
@Override
|
|
|
|
|
public RFuture<Boolean> get() {
|
|
|
|
|
return instance.retainAllAsync(c);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Publisher<Boolean> removeAll(final Collection<?> c) {
|
|
|
|
|
return reactive(new Supplier<RFuture<Boolean>>() {
|
|
|
|
|
@Override
|
|
|
|
|
public RFuture<Boolean> get() {
|
|
|
|
|
return instance.removeAllAsync(c);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return commandExecutor.writeReactive(instance.getName(), instance.getCodec(), RedisCommands.ZADD_RAW, params.toArray());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Publisher<Integer> addAll(Publisher<? extends V> c) {
|
|
|
|
|
return new PublisherAdder<V>() {
|
|
|
|
|
@Override
|
|
|
|
|