use of org.redisson.client.protocol.decoder.ScanObjectEntry in project redisson by redisson.
the class RedissonMapCache method scanIteratorAsync.
public RFuture<MapScanResult<ScanObjectEntry, ScanObjectEntry>> scanIteratorAsync(final String name, InetSocketAddress client, long startPos) {
RedisCommand<MapCacheScanResult<Object, Object>> EVAL_HSCAN = new RedisCommand<MapCacheScanResult<Object, Object>>("EVAL", new ListMultiDecoder(new LongMultiDecoder(), new ObjectMapDecoder(new MapScanCodec(codec)), new ObjectListDecoder(codec), new MapCacheScanResultReplayDecoder()), ValueType.MAP);
RFuture<MapCacheScanResult<ScanObjectEntry, ScanObjectEntry>> f = commandExecutor.evalReadAsync(client, name, codec, EVAL_HSCAN, "local result = {}; " + "local idleKeys = {}; " + "local res = redis.call('hscan', KEYS[1], ARGV[2]); " + "local currentTime = tonumber(ARGV[1]); " + "for i, value in ipairs(res[2]) do " + "if i % 2 == 0 then " + "local key = res[2][i-1]; " + "local expireDate = 92233720368547758; " + "local expireDateScore = redis.call('zscore', KEYS[2], key); " + "if expireDateScore ~= false then " + "expireDate = tonumber(expireDateScore) " + "end; " + "local t, val = struct.unpack('dLc0', value); " + "if t ~= 0 then " + "local expireIdle = redis.call('zscore', KEYS[3], key); " + "if expireIdle ~= false then " + "if tonumber(expireIdle) > currentTime and expireDate > currentTime then " + "table.insert(idleKeys, key); " + "end; " + "expireDate = math.min(expireDate, tonumber(expireIdle)) " + "end; " + "end; " + "if expireDate > currentTime then " + "table.insert(result, key); " + "table.insert(result, val); " + "end; " + "end; " + "end;" + "return {res[1], result, idleKeys};", Arrays.<Object>asList(name, getTimeoutSetName(name), getIdleSetName(name)), System.currentTimeMillis(), startPos);
f.addListener(new FutureListener<MapCacheScanResult<ScanObjectEntry, ScanObjectEntry>>() {
@Override
public void operationComplete(Future<MapCacheScanResult<ScanObjectEntry, ScanObjectEntry>> future) throws Exception {
if (future.isSuccess()) {
MapCacheScanResult<ScanObjectEntry, ScanObjectEntry> res = future.getNow();
if (res.getIdleKeys().isEmpty()) {
return;
}
List<Object> args = new ArrayList<Object>(res.getIdleKeys().size() + 1);
args.add(System.currentTimeMillis());
args.addAll(res.getIdleKeys());
commandExecutor.evalWriteAsync(name, codec, new RedisCommand<Map<Object, Object>>("EVAL", new MapGetAllDecoder(args, 1), 7, ValueType.MAP_KEY, ValueType.MAP_VALUE), // index is the first parameter
"local currentTime = tonumber(table.remove(ARGV, 1)); " + "local map = redis.call('hmget', KEYS[1], unpack(ARGV)); " + "for i = #map, 1, -1 do " + "local value = map[i]; " + "if value ~= false then " + "local key = ARGV[i]; " + "local t, val = struct.unpack('dLc0', value); " + "if t ~= 0 then " + "local expireIdle = redis.call('zscore', KEYS[2], key); " + "if expireIdle ~= false then " + "if tonumber(expireIdle) > currentTime then " + "local value = struct.pack('dLc0', t, string.len(val), val); " + "redis.call('hset', KEYS[1], key, value); " + "redis.call('zadd', KEYS[2], t + currentTime, key); " + "end; " + "end; " + "end; " + "end; " + "end; ", Arrays.<Object>asList(name, getIdleSetName(name)), args.toArray());
}
}
});
return (RFuture<MapScanResult<ScanObjectEntry, ScanObjectEntry>>) (Object) f;
}
use of org.redisson.client.protocol.decoder.ScanObjectEntry in project redisson by redisson.
the class RedissonMapReactiveIterator method stream.
public Publisher<M> stream() {
return new Stream<M>() {
@Override
public void subscribe(final Subscriber<? super M> t) {
t.onSubscribe(new ReactiveSubscription<M>(this, t) {
private Map<ByteBuf, ByteBuf> firstValues;
private long iterPos = 0;
private InetSocketAddress client;
private long currentIndex;
@Override
protected void onRequest(final long n) {
currentIndex = n;
nextValues();
}
private Map<ByteBuf, ByteBuf> convert(Map<ScanObjectEntry, ScanObjectEntry> map) {
Map<ByteBuf, ByteBuf> result = new HashMap<ByteBuf, ByteBuf>(map.size());
for (Entry<ScanObjectEntry, ScanObjectEntry> entry : map.entrySet()) {
result.put(entry.getKey().getBuf(), entry.getValue().getBuf());
}
return result;
}
protected void nextValues() {
final ReactiveSubscription<M> m = this;
map.scanIteratorReactive(client, iterPos).subscribe(new Subscriber<MapScanResult<ScanObjectEntry, ScanObjectEntry>>() {
@Override
public void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE);
}
@Override
public void onNext(MapScanResult<ScanObjectEntry, ScanObjectEntry> res) {
client = res.getRedisClient();
if (iterPos == 0 && firstValues == null) {
firstValues = convert(res.getMap());
} else if (convert(res.getMap()).equals(firstValues)) {
m.onComplete();
currentIndex = 0;
return;
}
iterPos = res.getPos();
for (Entry<ScanObjectEntry, ScanObjectEntry> entry : res.getMap().entrySet()) {
M val = getValue(entry);
m.onNext(val);
currentIndex--;
if (currentIndex == 0) {
m.onComplete();
return;
}
}
}
@Override
public void onError(Throwable error) {
m.onError(error);
}
@Override
public void onComplete() {
if (currentIndex == 0) {
return;
}
nextValues();
}
});
}
});
}
};
}
use of org.redisson.client.protocol.decoder.ScanObjectEntry in project redisson by redisson.
the class SetReactiveIterator method subscribe.
@Override
public void subscribe(final Subscriber<? super V> t) {
t.onSubscribe(new ReactiveSubscription<V>(this, t) {
private List<ByteBuf> firstValues;
private List<ByteBuf> lastValues;
private long nextIterPos;
private InetSocketAddress client;
private boolean finished;
@Override
protected void onRequest(long n) {
nextValues();
}
private void handle(List<ScanObjectEntry> vals) {
for (ScanObjectEntry val : vals) {
onNext((V) val.getObj());
}
}
protected void nextValues() {
final ReactiveSubscription<V> m = this;
scanIteratorReactive(client, nextIterPos).subscribe(new Subscriber<ListScanResult<ScanObjectEntry>>() {
@Override
public void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE);
}
@Override
public void onNext(ListScanResult<ScanObjectEntry> res) {
if (finished) {
free(firstValues);
free(lastValues);
client = null;
firstValues = null;
lastValues = null;
nextIterPos = 0;
return;
}
long prevIterPos = nextIterPos;
if (lastValues != null) {
free(lastValues);
}
lastValues = convert(res.getValues());
client = res.getRedisClient();
if (nextIterPos == 0 && firstValues == null) {
firstValues = lastValues;
lastValues = null;
if (firstValues.isEmpty()) {
client = null;
firstValues = null;
nextIterPos = 0;
prevIterPos = -1;
}
} else {
if (firstValues.isEmpty()) {
firstValues = lastValues;
lastValues = null;
if (firstValues.isEmpty()) {
if (res.getPos() == 0) {
finished = true;
m.onComplete();
return;
}
}
} else if (lastValues.removeAll(firstValues)) {
free(firstValues);
free(lastValues);
client = null;
firstValues = null;
lastValues = null;
nextIterPos = 0;
prevIterPos = -1;
finished = true;
m.onComplete();
return;
}
}
handle(res.getValues());
nextIterPos = res.getPos();
if (prevIterPos == nextIterPos) {
finished = true;
m.onComplete();
}
}
@Override
public void onError(Throwable error) {
m.onError(error);
}
@Override
public void onComplete() {
if (finished) {
return;
}
nextValues();
}
});
}
});
}
use of org.redisson.client.protocol.decoder.ScanObjectEntry in project redisson by redisson.
the class CommandAsyncService method handleReference.
private <R, V> void handleReference(RPromise<R> mainPromise, R res) {
if (res instanceof List) {
List<Object> r = (List<Object>) res;
for (int i = 0; i < r.size(); i++) {
if (r.get(i) instanceof RedissonReference) {
try {
r.set(i, redisson != null ? RedissonObjectFactory.fromReference(redisson, (RedissonReference) r.get(i)) : RedissonObjectFactory.fromReference(redissonReactive, (RedissonReference) r.get(i)));
} catch (Exception exception) {
//skip and carry on to next one.
}
} else if (r.get(i) instanceof ScoredEntry && ((ScoredEntry) r.get(i)).getValue() instanceof RedissonReference) {
try {
ScoredEntry<?> se = ((ScoredEntry<?>) r.get(i));
se = new ScoredEntry(se.getScore(), redisson != null ? RedissonObjectFactory.<R>fromReference(redisson, (RedissonReference) se.getValue()) : RedissonObjectFactory.<R>fromReference(redissonReactive, (RedissonReference) se.getValue()));
r.set(i, se);
} catch (Exception exception) {
//skip and carry on to next one.
}
}
}
mainPromise.trySuccess(res);
} else if (res instanceof ListScanResult) {
List<ScanObjectEntry> r = ((ListScanResult) res).getValues();
for (int i = 0; i < r.size(); i++) {
Object obj = r.get(i);
if (!(obj instanceof ScanObjectEntry)) {
break;
}
ScanObjectEntry e = r.get(i);
if (e.getObj() instanceof RedissonReference) {
try {
r.set(i, new ScanObjectEntry(e.getBuf(), redisson != null ? RedissonObjectFactory.<R>fromReference(redisson, (RedissonReference) e.getObj()) : RedissonObjectFactory.<R>fromReference(redissonReactive, (RedissonReference) e.getObj())));
} catch (Exception exception) {
//skip and carry on to next one.
}
} else if (e.getObj() instanceof ScoredEntry && ((ScoredEntry<?>) e.getObj()).getValue() instanceof RedissonReference) {
try {
ScoredEntry<?> se = ((ScoredEntry<?>) e.getObj());
se = new ScoredEntry(se.getScore(), redisson != null ? RedissonObjectFactory.<R>fromReference(redisson, (RedissonReference) se.getValue()) : RedissonObjectFactory.<R>fromReference(redissonReactive, (RedissonReference) se.getValue()));
r.set(i, new ScanObjectEntry(e.getBuf(), se));
} catch (Exception exception) {
//skip and carry on to next one.
}
}
}
mainPromise.trySuccess(res);
} else if (res instanceof MapScanResult) {
Map<ScanObjectEntry, ScanObjectEntry> map = ((MapScanResult) res).getMap();
HashMap<ScanObjectEntry, ScanObjectEntry> toAdd = null;
for (Map.Entry<ScanObjectEntry, ScanObjectEntry> e : map.entrySet()) {
if (e.getValue().getObj() instanceof RedissonReference) {
try {
e.setValue(new ScanObjectEntry(e.getValue().getBuf(), redisson != null ? RedissonObjectFactory.<R>fromReference(redisson, (RedissonReference) e.getValue().getObj()) : RedissonObjectFactory.<R>fromReference(redissonReactive, (RedissonReference) e.getValue().getObj())));
} catch (Exception exception) {
//skip and carry on to next one.
}
}
if (e.getKey().getObj() instanceof RedissonReference) {
if (toAdd == null) {
toAdd = new HashMap<ScanObjectEntry, ScanObjectEntry>();
}
toAdd.put(e.getKey(), e.getValue());
}
}
if (toAdd != null) {
for (Map.Entry<ScanObjectEntry, ScanObjectEntry> e : toAdd.entrySet()) {
try {
map.put(new ScanObjectEntry(e.getValue().getBuf(), (redisson != null ? RedissonObjectFactory.<R>fromReference(redisson, (RedissonReference) e.getKey().getObj()) : RedissonObjectFactory.<R>fromReference(redissonReactive, (RedissonReference) e.getKey().getObj()))), map.remove(e.getKey()));
} catch (Exception exception) {
//skip and carry on to next one.
}
}
}
mainPromise.trySuccess(res);
} else if (res instanceof RedissonReference) {
try {
mainPromise.trySuccess(redisson != null ? RedissonObjectFactory.<R>fromReference(redisson, (RedissonReference) res) : RedissonObjectFactory.<R>fromReference(redissonReactive, (RedissonReference) res));
} catch (Exception exception) {
//fallback
mainPromise.trySuccess(res);
}
} else {
mainPromise.trySuccess(res);
}
}
use of org.redisson.client.protocol.decoder.ScanObjectEntry in project redisson by redisson.
the class MapScanCodec method getMapValueDecoder.
@Override
public Decoder<Object> getMapValueDecoder() {
return new Decoder<Object>() {
@Override
public Object decode(ByteBuf buf, State state) throws IOException {
ByteBuf b = Unpooled.copiedBuffer(buf);
Codec c = delegate;
if (mapValueCodec != null) {
c = mapValueCodec;
}
Object val = c.getMapValueDecoder().decode(buf, state);
return new ScanObjectEntry(b, val);
}
};
}
Aggregations