
org.redisson.RedissonKeys Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of redisson Show documentation
Show all versions of redisson Show documentation
Redis Java client with features of In-Memory Data Grid
/**
* 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;
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 java.util.concurrent.atomic.AtomicLong;
import org.redisson.client.codec.StringCodec;
import org.redisson.client.protocol.RedisCommands;
import org.redisson.client.protocol.decoder.ListScanResult;
import org.redisson.cluster.ClusterSlotRange;
import org.redisson.command.CommandAsyncExecutor;
import org.redisson.core.RKeys;
import org.redisson.misc.CompositeIterable;
import io.netty.util.concurrent.Future;
public class RedissonKeys implements RKeys {
private final CommandAsyncExecutor commandExecutor;
public RedissonKeys(CommandAsyncExecutor commandExecutor) {
super();
this.commandExecutor = commandExecutor;
}
@Override
public int getSlot(String key) {
return commandExecutor.get(getSlotAsync(key));
}
@Override
public Future getSlotAsync(String key) {
return commandExecutor.readAsync(null, RedisCommands.KEYSLOT, key);
}
@Override
public Iterable getKeysByPattern(final String pattern) {
List> iterables = new ArrayList>();
for (final ClusterSlotRange slot : commandExecutor.getConnectionManager().getEntries().keySet()) {
Iterable iterable = new Iterable() {
@Override
public Iterator iterator() {
return createKeysIterator(slot.getStartSlot(), pattern);
}
};
iterables.add(iterable);
}
return new CompositeIterable(iterables);
}
@Override
public Iterable getKeys() {
return getKeysByPattern(null);
}
private ListScanResult scanIterator(int slot, long startPos, String pattern) {
if (pattern == null) {
Future> f = commandExecutor.writeAsync(slot, StringCodec.INSTANCE, RedisCommands.SCAN, startPos);
return commandExecutor.get(f);
}
Future> f = commandExecutor.writeAsync(slot, StringCodec.INSTANCE, RedisCommands.SCAN, startPos, "MATCH", pattern);
return commandExecutor.get(f);
}
private Iterator createKeysIterator(final int slot, final String pattern) {
return new Iterator() {
private List firstValues;
private Iterator iter;
private long iterPos;
private boolean removeExecuted;
private String value;
@Override
public boolean hasNext() {
if (iter == null || !iter.hasNext()) {
ListScanResult res = scanIterator(slot, iterPos, pattern);
if (iterPos == 0 && firstValues == null) {
firstValues = res.getValues();
} else if (res.getValues().equals(firstValues)) {
return false;
}
iter = res.getValues().iterator();
iterPos = res.getPos();
}
return iter.hasNext();
}
@Override
public String next() {
if (!hasNext()) {
throw new NoSuchElementException("No such element");
}
value = iter.next();
removeExecuted = false;
return value;
}
@Override
public void remove() {
if (removeExecuted) {
throw new IllegalStateException("Element been already deleted");
}
if (iter == null) {
throw new IllegalStateException();
}
iter.remove();
delete(value);
removeExecuted = true;
}
};
}
@Override
public String randomKey() {
return commandExecutor.get(randomKeyAsync());
}
@Override
public Future randomKeyAsync() {
return commandExecutor.readRandomAsync(RedisCommands.RANDOM_KEY);
}
/**
* Find keys by key search pattern
*
* Supported glob-style patterns:
* h?llo subscribes to hello, hallo and hxllo
* h*llo subscribes to hllo and heeeello
* h[ae]llo subscribes to hello and hallo, but not hillo
*
* @param pattern
* @return
*/
@Override
public Collection findKeysByPattern(String pattern) {
return commandExecutor.get(findKeysByPatternAsync(pattern));
}
/**
* Find keys by key search pattern in async mode
*
* Supported glob-style patterns:
* h?llo subscribes to hello, hallo and hxllo
* h*llo subscribes to hllo and heeeello
* h[ae]llo subscribes to hello and hallo, but not hillo
*
* @param pattern
* @return
*/
@Override
public Future> findKeysByPatternAsync(String pattern) {
return commandExecutor.readAllAsync(RedisCommands.KEYS, pattern);
}
/**
* Delete multiple objects by a key pattern
*
* Supported glob-style patterns:
* h?llo subscribes to hello, hallo and hxllo
* h*llo subscribes to hllo and heeeello
* h[ae]llo subscribes to hello and hallo, but not hillo
*
* @param pattern
* @return
*/
@Override
public long deleteByPattern(String pattern) {
return commandExecutor.get(deleteByPatternAsync(pattern));
}
/**
* Delete multiple objects by a key pattern in async mode
*
* Supported glob-style patterns:
* h?llo subscribes to hello, hallo and hxllo
* h*llo subscribes to hllo and heeeello
* h[ae]llo subscribes to hello and hallo, but not hillo
*
* @param pattern
* @return
*/
@Override
public Future deleteByPatternAsync(String pattern) {
return commandExecutor.evalWriteAllAsync(RedisCommands.EVAL_LONG, new SlotCallback() {
AtomicLong results = new AtomicLong();
@Override
public void onSlotResult(Long result) {
results.addAndGet(result);
}
@Override
public Long onFinish() {
return results.get();
}
}, "local keys = redis.call('keys', ARGV[1]) "
+ "local n = 0 "
+ "for i=1, table.getn(keys),5000 do "
+ "n = n + redis.call('del', unpack(keys, i, math.min(i+4999, table.getn(keys)))) "
+ "end "
+ "return n;",Collections.emptyList(), pattern);
}
/**
* Delete multiple objects by name
*
* @param keys - object names
* @return
*/
@Override
public long delete(String ... keys) {
return commandExecutor.get(deleteAsync(keys));
}
/**
* Delete multiple objects by name in async mode
*
* @param keys - object names
* @return
*/
@Override
public Future deleteAsync(String ... keys) {
return commandExecutor.writeAllAsync(RedisCommands.DEL, new SlotCallback() {
AtomicLong results = new AtomicLong();
@Override
public void onSlotResult(Long result) {
results.addAndGet(result);
}
@Override
public Long onFinish() {
return results.get();
}
}, (Object[])keys);
}
@Override
public Long count() {
return commandExecutor.get(countAsync());
}
@Override
public Future countAsync() {
return commandExecutor.readAllAsync(RedisCommands.DBSIZE, new SlotCallback() {
AtomicLong results = new AtomicLong();
@Override
public void onSlotResult(Long result) {
results.addAndGet(result);
}
@Override
public Long onFinish() {
return results.get();
}
});
}
@Override
public void flushdb() {
commandExecutor.get(flushdbAsync());
}
@Override
public Future flushdbAsync() {
return commandExecutor.writeAllAsync(RedisCommands.FLUSHDB);
}
@Override
public void flushall() {
commandExecutor.get(flushallAsync());
}
@Override
public Future flushallAsync() {
return commandExecutor.writeAllAsync(RedisCommands.FLUSHALL);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy