redis.clients.jedis.Jedis Maven / Gradle / Ivy
Show all versions of jedis_preview Show documentation
package redis.clients.jedis;
import static redis.clients.jedis.Protocol.Command.*;
import static redis.clients.jedis.Protocol.Keyword.*;
import static redis.clients.jedis.Protocol.SentinelKeyword.*;
import static redis.clients.jedis.Protocol.toByteArray;
import static redis.clients.jedis.util.SafeEncoder.encode;
import java.io.Closeable;
import java.net.URI;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocketFactory;
import redis.clients.jedis.Protocol.*;
import redis.clients.jedis.args.*;
import redis.clients.jedis.commands.*;
import redis.clients.jedis.exceptions.InvalidURIException;
import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisException;
import redis.clients.jedis.params.*;
import redis.clients.jedis.resps.*;
import redis.clients.jedis.util.JedisURIHelper;
import redis.clients.jedis.util.KeyValue;
import redis.clients.jedis.util.Pool;
public class Jedis implements ServerCommands, DatabaseCommands, JedisCommands, JedisBinaryCommands,
ControlCommands, ControlBinaryCommands, ClusterCommands, ModuleCommands, GenericControlCommands,
SentinelCommands, Closeable {
protected final Connection connection;
private final CommandObjects commandObjects = new CommandObjects();
private int db = 0;
private Transaction transaction = null;
private boolean isInMulti = false;
private boolean isInWatch = false;
private Pipeline pipeline = null;
protected static final byte[][] DUMMY_ARRAY = new byte[0][];
private Pool dataSource = null;
public Jedis() {
connection = new Connection();
}
/**
* This constructor only accepts a URI string. {@link JedisURIHelper#isValid(java.net.URI)} can be
* used before this.
* @param url
*/
public Jedis(final String url) {
this(URI.create(url));
}
public Jedis(final HostAndPort hp) {
connection = new Connection(hp);
}
public Jedis(final String host, final int port) {
connection = new Connection(host, port);
}
public Jedis(final String host, final int port, final JedisClientConfig config) {
this(new HostAndPort(host, port), config);
}
public Jedis(final HostAndPort hostPort, final JedisClientConfig config) {
connection = new Connection(hostPort, config);
RedisProtocol proto = config.getRedisProtocol();
if (proto != null) commandObjects.setProtocol(proto);
}
public Jedis(final String host, final int port, final boolean ssl) {
this(host, port, DefaultJedisClientConfig.builder().ssl(ssl).build());
}
public Jedis(final String host, final int port, final boolean ssl,
final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters,
final HostnameVerifier hostnameVerifier) {
this(host, port, DefaultJedisClientConfig.builder().ssl(ssl)
.sslSocketFactory(sslSocketFactory).sslParameters(sslParameters)
.hostnameVerifier(hostnameVerifier).build());
}
public Jedis(final String host, final int port, final int timeout) {
this(host, port, timeout, timeout);
}
public Jedis(final String host, final int port, final int timeout, final boolean ssl) {
this(host, port, timeout, timeout, ssl);
}
public Jedis(final String host, final int port, final int timeout, final boolean ssl,
final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters,
final HostnameVerifier hostnameVerifier) {
this(host, port, timeout, timeout, ssl, sslSocketFactory, sslParameters, hostnameVerifier);
}
public Jedis(final String host, final int port, final int connectionTimeout,
final int soTimeout) {
this(host, port, DefaultJedisClientConfig.builder()
.connectionTimeoutMillis(connectionTimeout).socketTimeoutMillis(soTimeout).build());
}
public Jedis(final String host, final int port, final int connectionTimeout,
final int soTimeout, final int infiniteSoTimeout) {
this(host, port, DefaultJedisClientConfig.builder()
.connectionTimeoutMillis(connectionTimeout).socketTimeoutMillis(soTimeout)
.blockingSocketTimeoutMillis(infiniteSoTimeout).build());
}
public Jedis(final String host, final int port, final int connectionTimeout,
final int soTimeout, final boolean ssl) {
this(host, port, DefaultJedisClientConfig.builder()
.connectionTimeoutMillis(connectionTimeout).socketTimeoutMillis(soTimeout).ssl(ssl)
.build());
}
public Jedis(final String host, final int port, final int connectionTimeout,
final int soTimeout, final boolean ssl, final SSLSocketFactory sslSocketFactory,
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
this(host, port, DefaultJedisClientConfig.builder()
.connectionTimeoutMillis(connectionTimeout).socketTimeoutMillis(soTimeout).ssl(ssl)
.sslSocketFactory(sslSocketFactory).sslParameters(sslParameters)
.hostnameVerifier(hostnameVerifier).build());
}
public Jedis(final String host, final int port, final int connectionTimeout,
final int soTimeout, final int infiniteSoTimeout, final boolean ssl,
final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters,
final HostnameVerifier hostnameVerifier) {
this(host, port, DefaultJedisClientConfig.builder()
.connectionTimeoutMillis(connectionTimeout).socketTimeoutMillis(soTimeout)
.blockingSocketTimeoutMillis(infiniteSoTimeout).ssl(ssl)
.sslSocketFactory(sslSocketFactory).sslParameters(sslParameters)
.hostnameVerifier(hostnameVerifier).build());
}
public Jedis(URI uri) {
if (!JedisURIHelper.isValid(uri)) {
throw new InvalidURIException(String.format(
"Cannot open Redis connection due invalid URI \"%s\".", uri.toString()));
}
connection = new Connection(new HostAndPort(uri.getHost(), uri.getPort()),
DefaultJedisClientConfig.builder().user(JedisURIHelper.getUser(uri))
.password(JedisURIHelper.getPassword(uri)).database(JedisURIHelper.getDBIndex(uri))
.protocol(JedisURIHelper.getRedisProtocol(uri))
.ssl(JedisURIHelper.isRedisSSLScheme(uri)).build());
}
public Jedis(URI uri, final SSLSocketFactory sslSocketFactory,
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
this(uri, DefaultJedisClientConfig.builder().sslSocketFactory(sslSocketFactory)
.sslParameters(sslParameters).hostnameVerifier(hostnameVerifier).build());
}
public Jedis(final URI uri, final int timeout) {
this(uri, timeout, timeout);
}
public Jedis(final URI uri, final int timeout, final SSLSocketFactory sslSocketFactory,
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
this(uri, timeout, timeout, sslSocketFactory, sslParameters, hostnameVerifier);
}
public Jedis(final URI uri, final int connectionTimeout, final int soTimeout) {
this(uri, DefaultJedisClientConfig.builder().connectionTimeoutMillis(connectionTimeout)
.socketTimeoutMillis(soTimeout).build());
}
public Jedis(final URI uri, final int connectionTimeout, final int soTimeout,
final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters,
final HostnameVerifier hostnameVerifier) {
this(uri, DefaultJedisClientConfig.builder().connectionTimeoutMillis(connectionTimeout)
.socketTimeoutMillis(soTimeout).sslSocketFactory(sslSocketFactory)
.sslParameters(sslParameters).hostnameVerifier(hostnameVerifier).build());
}
public Jedis(final URI uri, final int connectionTimeout, final int soTimeout,
final int infiniteSoTimeout, final SSLSocketFactory sslSocketFactory,
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
this(uri, DefaultJedisClientConfig.builder().connectionTimeoutMillis(connectionTimeout)
.socketTimeoutMillis(soTimeout).blockingSocketTimeoutMillis(infiniteSoTimeout)
.sslSocketFactory(sslSocketFactory).sslParameters(sslParameters)
.hostnameVerifier(hostnameVerifier).build());
}
public Jedis(final URI uri, JedisClientConfig config) {
if (!JedisURIHelper.isValid(uri)) {
throw new InvalidURIException(String.format(
"Cannot open Redis connection due invalid URI \"%s\".", uri.toString()));
}
connection = new Connection(new HostAndPort(uri.getHost(), uri.getPort()),
DefaultJedisClientConfig.builder()
.connectionTimeoutMillis(config.getConnectionTimeoutMillis())
.socketTimeoutMillis(config.getSocketTimeoutMillis())
.blockingSocketTimeoutMillis(config.getBlockingSocketTimeoutMillis())
.user(JedisURIHelper.getUser(uri)).password(JedisURIHelper.getPassword(uri))
.database(JedisURIHelper.getDBIndex(uri)).clientName(config.getClientName())
.protocol(JedisURIHelper.getRedisProtocol(uri))
.ssl(JedisURIHelper.isRedisSSLScheme(uri)).sslSocketFactory(config.getSslSocketFactory())
.sslParameters(config.getSslParameters()).hostnameVerifier(config.getHostnameVerifier())
.build());
RedisProtocol proto = config.getRedisProtocol();
if (proto != null) commandObjects.setProtocol(proto);
}
public Jedis(final JedisSocketFactory jedisSocketFactory) {
connection = new Connection(jedisSocketFactory);
}
public Jedis(final JedisSocketFactory jedisSocketFactory, final JedisClientConfig clientConfig) {
connection = new Connection(jedisSocketFactory, clientConfig);
RedisProtocol proto = clientConfig.getRedisProtocol();
if (proto != null) commandObjects.setProtocol(proto);
}
public Jedis(final Connection connection) {
this.connection = connection;
}
@Override
public String toString() {
return "Jedis{" + connection + '}';
}
// Legacy
public Connection getClient() {
return getConnection();
}
public Connection getConnection() {
return connection;
}
// Legacy
public void connect() {
connection.connect();
}
/**
* Closing the socket will disconnect the server connection.
*/
public void disconnect() {
connection.disconnect();
}
public boolean isConnected() {
return connection.isConnected();
}
public boolean isBroken() {
return connection.isBroken();
}
public void resetState() {
if (isConnected()) {
if (transaction != null) {
transaction.close();
}
if (pipeline != null) {
pipeline.close();
}
// connection.resetState();
if (isInWatch) {
connection.sendCommand(UNWATCH);
connection.getStatusCodeReply();
isInWatch = false;
}
}
transaction = null;
pipeline = null;
}
protected void setDataSource(Pool jedisPool) {
this.dataSource = jedisPool;
}
@Override
public void close() {
if (dataSource != null) {
Pool pool = this.dataSource;
this.dataSource = null;
if (isBroken()) {
pool.returnBrokenResource(this);
} else {
pool.returnResource(this);
}
} else {
connection.close();
}
}
// Legacy
public Transaction multi() {
transaction = new Transaction(this);
return transaction;
}
// Legacy
public Pipeline pipelined() {
pipeline = new Pipeline(this);
return pipeline;
}
// Legacy
protected void checkIsInMultiOrPipeline() {
// if (connection.isInMulti()) {
if (transaction != null) {
throw new IllegalStateException(
"Cannot use Jedis when in Multi. Please use Transaction or reset jedis state.");
} else if (pipeline != null && pipeline.hasPipelinedResponse()) {
throw new IllegalStateException(
"Cannot use Jedis when in Pipeline. Please use Pipeline or reset jedis state.");
}
}
public int getDB() {
return this.db;
}
/**
* @return PONG
*/
@Override
public String ping() {
checkIsInMultiOrPipeline();
connection.sendCommand(Command.PING);
return connection.getStatusCodeReply();
}
/**
* Works same as {@link Jedis#ping()} but returns argument message instead of PONG
.
* @param message
* @return message
*/
public byte[] ping(final byte[] message) {
checkIsInMultiOrPipeline();
connection.sendCommand(Command.PING, message);
return connection.getBinaryBulkReply();
}
/**
* Select the DB with having the specified zero-based numeric index. For default every new
* connection is automatically selected to DB 0.
* @param index
* @return OK
*/
@Override
public String select(final int index) {
checkIsInMultiOrPipeline();
connection.sendCommand(SELECT, toByteArray(index));
String statusCodeReply = connection.getStatusCodeReply();
this.db = index;
return statusCodeReply;
}
@Override
public String swapDB(final int index1, final int index2) {
checkIsInMultiOrPipeline();
connection.sendCommand(SWAPDB, toByteArray(index1), toByteArray(index2));
return connection.getStatusCodeReply();
}
/**
* Delete all the keys of the currently selected DB. This command never fails.
* @return OK
*/
@Override
public String flushDB() {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.flushDB());
}
/**
* Delete all the keys of the currently selected DB. This command never fails.
* @param flushMode
* @return OK
*/
@Override
public String flushDB(FlushMode flushMode) {
checkIsInMultiOrPipeline();
connection.sendCommand(FLUSHDB, flushMode.getRaw());
return connection.getStatusCodeReply();
}
/**
* Delete all the keys of all the existing databases, not just the currently selected one. This
* command never fails.
* @return OK
*/
@Override
public String flushAll() {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.flushAll());
}
/**
* Delete all the keys of all the existing databases, not just the currently selected one. This
* command never fails.
* @param flushMode
* @return OK
*/
@Override
public String flushAll(FlushMode flushMode) {
checkIsInMultiOrPipeline();
connection.sendCommand(FLUSHALL, flushMode.getRaw());
return connection.getStatusCodeReply();
}
/**
* COPY source destination [DB destination-db] [REPLACE]
*
* @param srcKey the source key.
* @param dstKey the destination key.
* @param db
* @param replace
*/
@Override
public boolean copy(byte[] srcKey, byte[] dstKey, int db, boolean replace) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.copy(srcKey, dstKey, db, replace));
}
/**
* COPY source destination [DB destination-db] [REPLACE]
*
* @param srcKey the source key.
* @param dstKey the destination key.
* @param replace
*/
@Override
public boolean copy(byte[] srcKey, byte[] dstKey, boolean replace) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.copy(srcKey, dstKey, replace));
}
/**
* Set the string value as value of the key. The string can't be longer than 1073741824 bytes (1
* GB).
*
* Time complexity: O(1)
* @param key
* @param value
* @return OK
*/
@Override
public String set(final byte[] key, final byte[] value) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.set(key, value));
}
/**
* Set the string value as value of the key. The string can't be longer than 1073741824 bytes (1
* GB).
* @param key
* @param value
* @param params NX|XX, NX -- Only set the key if it does not already exist. XX -- Only set the
* key if it already exists. EX|PX, expire time units: EX = seconds; PX = milliseconds
* @return simple-string-reply {@code OK} if {@code SET} was executed correctly, or {@code null}
* if the {@code SET} operation was not performed because the user specified the NX or XX option
* but the condition was not met.
*/
@Override
public String set(final byte[] key, final byte[] value, final SetParams params) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.set(key, value, params));
}
/**
* Get the value of the specified key. If the key does not exist the special value 'nil' is
* returned. If the value stored at key is not a string an error is returned because GET can only
* handle string values.
*
* Time complexity: O(1)
* @param key
* @return Bulk reply
*/
@Override
public byte[] get(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.get(key));
}
@Override
public byte[] setGet(final byte[] key, final byte[] value) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.setGet(key, value));
}
@Override
public byte[] setGet(final byte[] key, final byte[] value, final SetParams params) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.setGet(key, value, params));
}
/**
* Get the value of key and delete the key. This command is similar to GET, except for the fact
* that it also deletes the key on success (if and only if the key's value type is a string).
*
* Time complexity: O(1)
* @param key
* @return The value of key
*/
@Override
public byte[] getDel(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.getDel(key));
}
@Override
public byte[] getEx(final byte[] key, final GetExParams params) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.getEx(key, params));
}
/**
* Test if the specified keys exist. The command returns the number of keys exist.
* Time complexity: O(N)
* @param keys
* @return An integer greater than 0 if one or more keys exist, 0 if none of the specified keys exist
*/
@Override
public long exists(final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.exists(keys));
}
/**
* Test if the specified key exists. The command returns true if the key exists, otherwise false is
* returned. Note that even keys set with an empty string as value will return true. Time
* complexity: O(1)
* @param key
* @return {@code true} if the key exists, otherwise {@code false}
*/
@Override
public boolean exists(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.exists(key));
}
/**
* Remove the specified keys. If a given key does not exist no operation is performed for this
* key. The command returns the number of keys removed. Time complexity: O(1)
* @param keys
* @return The number of keys that were removed
*/
@Override
public long del(final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.del(keys));
}
@Override
public long del(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.del(key));
}
/**
* This command is very similar to DEL: it removes the specified keys. Just like DEL a key is
* ignored if it does not exist. However, the command performs the actual memory reclaiming in a
* different thread, so it is not blocking, while DEL is. This is where the command name comes
* from: the command just unlinks the keys from the keyspace. The actual removal will happen later
* asynchronously.
*
* Time complexity: O(1) for each key removed regardless of its size. Then the command does O(N)
* work in a different thread in order to reclaim memory, where N is the number of allocations the
* deleted objects where composed of.
* @param keys
* @return The number of keys that were unlinked
*/
@Override
public long unlink(final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.unlink(keys));
}
@Override
public long unlink(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.unlink(key));
}
/**
* Return the type of the value stored at key in form of a string. The type can be one of "none",
* "string", "list", "set". "none" is returned if the key does not exist. Time complexity: O(1)
* @param key
* @return "none" if the key does not exist, "string" if the key contains a String value, "list"
* if the key contains a List value, "set" if the key contains a Set value, "zset" if the key
* contains a Sorted Set value, "hash" if the key contains a Hash value
*/
@Override
public String type(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.type(key));
}
/**
* Returns all the keys matching the glob-style pattern as space separated strings. For example if
* you have in the database the keys "foo" and "foobar" the command "KEYS foo*" will return
* "foo foobar".
*
* Note that while the time complexity for this operation is O(n) the constant times are pretty
* low. For example Redis running on an entry level laptop can scan a 1 million keys database in
* 40 milliseconds. Still it's better to consider this one of the slow commands that may ruin
* the DB performance if not used with care.
*
* In other words this command is intended only for debugging and special operations like creating
* a script to change the DB schema. Don't use it in your normal code. Use Redis Sets in order to
* group together a subset of objects.
*
* Glob style patterns examples:
*
* - h?llo will match hello hallo hhllo
*
- h*llo will match hllo heeeello
*
- h[ae]llo will match hello and hallo, but not hillo
*
*
* Use \ to escape special chars if you want to match them verbatim.
*
* Time complexity: O(n) (with n being the number of keys in the DB, and assuming keys and pattern
* of limited length)
* @param pattern
* @return Multi bulk reply
*/
@Override
public Set keys(final byte[] pattern) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.keys(pattern));
}
/**
* Return a randomly selected key from the currently selected DB.
*
* Time complexity: O(1)
* @return The randomly selected key or an empty string is the database is empty
*/
@Override
public byte[] randomBinaryKey() {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.randomBinaryKey());
}
/**
* Atomically renames the key oldkey to newkey. If the source and destination name are the same an
* error is returned. If newkey already exists it is overwritten.
*
* Time complexity: O(1)
* @param oldkey
* @param newkey
* @return OK
*/
@Override
public String rename(final byte[] oldkey, final byte[] newkey) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.rename(oldkey, newkey));
}
/**
* Rename oldkey into newkey but fails if the destination key newkey already exists.
*
* Time complexity: O(1)
* @param oldkey
* @param newkey
* @return 1 if the key was renamed 0 if the target key already exist
*/
@Override
public long renamenx(final byte[] oldkey, final byte[] newkey) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.renamenx(oldkey, newkey));
}
/**
* Return the number of keys in the currently selected database.
* @return The number of keys
*/
@Override
public long dbSize() {
checkIsInMultiOrPipeline();
connection.sendCommand(DBSIZE);
return connection.getIntegerReply();
}
/**
* Set a timeout on the specified key. After the timeout the key will be automatically deleted by
* the server. A key with an associated timeout is said to be volatile in Redis terminology.
*
* Volatile keys are stored on disk like the other keys, the timeout is persistent too like all
* the other aspects of the dataset. Saving a dataset containing expires and stopping the server
* does not stop the flow of time as Redis stores on disk the time when the key will no longer be
* available as Unix time, and not the remaining seconds.
*
* Since Redis 2.1.3 you can update the value of the timeout of a key already having an expire
* set. It is also possible to undo the expire at all turning the key into a normal key using the
* {@link Jedis#persist(byte[]) PERSIST} command.
*
* Time complexity: O(1)
* @see Expire Command
* @param key
* @param seconds
* @return 1: the timeout was set. 0: the timeout was not set.
*/
@Override
public long expire(final byte[] key, final long seconds) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.expire(key, seconds));
}
@Override
public long expire(final byte[] key, final long seconds, final ExpiryOption expiryOption) {
checkIsInMultiOrPipeline();
return connection.executeCommand((commandObjects.expire(key, seconds, expiryOption)));
}
/**
* Set a timeout on the specified key. After the timeout the key will be automatically deleted by
* the server. A key with an associated timeout is said to be volatile in Redis terminology.
*
* Volatile keys are stored on disk like the other keys, the timeout is persistent too like all
* the other aspects of the dataset. Saving a dataset containing expires and stopping the server
* does not stop the flow of time as Redis stores on disk the time when the key will no longer be
* available as Unix time, and not the remaining milliseconds.
*
* Since Redis 2.1.3 you can update the value of the timeout of a key already having an expire
* set. It is also possible to undo the expire at all turning the key into a normal key using the
* {@link Jedis#persist(byte[]) PERSIST} command.
*
* Time complexity: O(1)
* @see PEXPIRE Command
* @param key
* @param milliseconds
* @return 1: the timeout was set. 0: the timeout was not set.
*/
@Override
public long pexpire(final byte[] key, final long milliseconds) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.pexpire(key, milliseconds));
}
@Override
public long pexpire(final byte[] key, final long milliseconds, final ExpiryOption expiryOption) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.pexpire(key, milliseconds, expiryOption));
}
@Override
public long expireTime(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand((commandObjects.expireTime(key)));
}
@Override
public long pexpireTime(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.pexpireTime(key));
}
/**
* EXPIREAT works exactly like {@link Jedis#expire(byte[], long) EXPIRE} but instead to get the
* number of seconds representing the Time To Live of the key as a second argument (that is a
* relative way of specifying the TTL), it takes an absolute one in the form of a UNIX timestamp
* (Number of seconds elapsed since 1 Gen 1970).
*
* EXPIREAT was introduced in order to implement the Append Only File persistence mode so that
* EXPIRE commands are automatically translated into EXPIREAT commands for the append only file.
* Of course EXPIREAT can also used by programmers that need a way to simply specify that a given
* key should expire at a given time in the future.
*
* Since Redis 2.1.3 you can update the value of the timeout of a key already having an expire
* set. It is also possible to undo the expire at all turning the key into a normal key using the
* {@link Jedis#persist(byte[]) PERSIST} command.
*
* Time complexity: O(1)
* @see Expire Command
* @param key
* @param unixTime
* @return 1: the timeout was set. 0: the timeout was not set since
* the key already has an associated timeout (this may happen only in Redis versions <
* 2.1.3, Redis >= 2.1.3 will happily update the timeout), or the key does not exist.
*/
@Override
public long expireAt(final byte[] key, final long unixTime) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.expireAt(key, unixTime));
}
@Override
public long expireAt(byte[] key, long unixTime, ExpiryOption expiryOption) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.expireAt(key, unixTime, expiryOption));
}
@Override
public long pexpireAt(final byte[] key, final long millisecondsTimestamp) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.pexpireAt(key, millisecondsTimestamp));
}
@Override
public long pexpireAt(byte[] key, long millisecondsTimestamp, ExpiryOption expiryOption) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.pexpireAt(key, millisecondsTimestamp, expiryOption));
}
/**
* The TTL command returns the remaining time to live in seconds of a key that has an
* {@link Jedis#expire(byte[], long) EXPIRE} set. This introspection capability allows a Redis
* connection to check how many seconds a given key will continue to be part of the dataset.
* @param key
* @return TTL in seconds, or a negative value in order to signal an error
*/
@Override
public long ttl(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.ttl(key));
}
/**
* Alters the last access time of a key(s). A key is ignored if it does not exist.
* Time complexity: O(N) where N is the number of keys that will be touched.
* @param keys
* @return The number of keys that were touched.
*/
@Override
public long touch(final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.touch(keys));
}
@Override
public long touch(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.touch(key));
}
/**
* Move the specified key from the currently selected DB to the specified destination DB. Note
* that this command returns 1 only if the key was successfully moved, and 0 if the target key was
* already there or if the source key was not found at all, so it is possible to use MOVE as a
* locking primitive.
* @param key
* @param dbIndex
* @return 1 if the key was moved 0 if the key was not moved because
* already present on the target DB or was not found in the current DB.
*/
@Override
public long move(final byte[] key, final int dbIndex) {
checkIsInMultiOrPipeline();
connection.sendCommand(MOVE, key, toByteArray(dbIndex));
return connection.getIntegerReply();
}
/**
* GETSET is an atomic set this value and return the old value command. Set key to the string
* value and return the old value stored at key. The string can't be longer than 1073741824 bytes
* (1 GB).
*
* Time complexity: O(1)
* @param key
* @param value
* @return Bulk reply
*/
@Override
public byte[] getSet(final byte[] key, final byte[] value) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.getSet(key, value));
}
/**
* Get the values of all the specified keys. If one or more keys don't exist or is not of type
* String, a 'nil' value is returned instead of the value of the specified key, but the operation
* never fails.
*
* Time complexity: O(1) for every key
* @param keys
* @return Multi bulk reply
*/
@Override
public List mget(final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.mget(keys));
}
/**
* SETNX works exactly like {@link Jedis#set(byte[], byte[]) SET} with the only difference that if
* the key already exists no operation is performed. SETNX actually means "SET if Not eXists".
*
* Time complexity: O(1)
* @param key
* @param value
* @return 1 if the key was set 0 if the key was not set
*/
@Override
public long setnx(final byte[] key, final byte[] value) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.setnx(key, value));
}
/**
* The command is exactly equivalent to the following group of commands:
* {@link Jedis#set(byte[], byte[]) SET} + {@link Jedis#expire(byte[], long) EXPIRE}. The
* operation is atomic.
*
* Time complexity: O(1)
* @param key
* @param seconds
* @param value
* @return OK
*/
@Override
public String setex(final byte[] key, final long seconds, final byte[] value) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.setex(key, seconds, value));
}
/**
* Set the respective keys to the respective values. MSET will replace old values with new
* values, while {@link Jedis#msetnx(byte[][]) MSETNX} will not perform any operation at all even
* if just a single key already exists.
*
* Because of this semantic MSETNX can be used in order to set different keys representing
* different fields of an unique logic object in a way that ensures that either all the fields or
* none at all are set.
*
* Both MSET and MSETNX are atomic operations. This means that for instance if the keys A and B
* are modified, another connection talking to Redis can either see the changes to both A and B at
* once, or no modification at all.
* @see Jedis#msetnx(byte[][])
* @param keysvalues
* @return OK
*/
@Override
public String mset(final byte[]... keysvalues) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.mset(keysvalues));
}
/**
* Set the respective keys to the respective values. {@link Jedis#mset(byte[][]) MSET} will
* replace old values with new values, while MSETNX will not perform any operation at all even if
* just a single key already exists.
*
* Because of this semantic MSETNX can be used in order to set different keys representing
* different fields of an unique logic object in a way that ensures that either all the fields or
* none at all are set.
*
* Both MSET and MSETNX are atomic operations. This means that for instance if the keys A and B
* are modified, another connection talking to Redis can either see the changes to both A and B at
* once, or no modification at all.
* @see Jedis#mset(byte[][])
* @param keysvalues
* @return 1 if the all the keys were set 0 if no key was set (at
* least one key already existed)
*/
@Override
public long msetnx(final byte[]... keysvalues) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.msetnx(keysvalues));
}
/**
* DECRBY work just like {@link Jedis#decr(byte[]) DECR} but instead to decrement by 1 the
* decrement is integer.
*
* DECR commands are limited to 64-bit signed integers.
*
* Note: this is actually a string operation, that is, in Redis there are not "integer" types.
* Simply the string stored at the key is parsed as a base 10 64-bit signed integer, incremented,
* and then converted back as a string.
*
* Time complexity: O(1)
* @see Jedis#incr(byte[])
* @see Jedis#decr(byte[])
* @see Jedis#incrBy(byte[], long)
* @param key
* @param decrement
* @return The value of key after the decrement
*/
@Override
public long decrBy(final byte[] key, final long decrement) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.decrBy(key, decrement));
}
/**
* Decrement the number stored at key by one. If the key does not exist or contains a value of a
* wrong type, set the key to the value of "0" before to perform the decrement operation.
*
* DECR commands are limited to 64-bit signed integers.
*
* Note: this is actually a string operation, that is, in Redis there are not "integer" types.
* Simply the string stored at the key is parsed as a base 10 64-bit signed integer, incremented,
* and then converted back as a string.
*
* Time complexity: O(1)
* @see Jedis#incr(byte[])
* @see Jedis#incrBy(byte[], long)
* @see Jedis#decrBy(byte[], long)
* @param key
* @return The value of key after the decrement
*/
@Override
public long decr(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.decr(key));
}
/**
* INCRBY work just like {@link Jedis#incr(byte[]) INCR} but instead to increment by 1 the
* increment is integer.
*
* INCR commands are limited to 64-bit signed integers.
*
* Note: this is actually a string operation, that is, in Redis there are not "integer" types.
* Simply the string stored at the key is parsed as a base 10 64-bit signed integer, incremented,
* and then converted back as a string.
*
* Time complexity: O(1)
* @see Jedis#incr(byte[])
* @see Jedis#decr(byte[])
* @see Jedis#decrBy(byte[], long)
* @param key
* @param increment
* @return The value of key after the increment
*/
@Override
public long incrBy(final byte[] key, final long increment) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.incrBy(key, increment));
}
/**
* INCRBYFLOAT work just like {@link Jedis#incrBy(byte[], long)} INCRBY} but increments by floats
* instead of integers.
*
* INCRBYFLOAT commands are limited to double precision floating point values.
*
* Note: this is actually a string operation, that is, in Redis there are not "double" types.
* Simply the string stored at the key is parsed as a base double precision floating point value,
* incremented, and then converted back as a string. There is no DECRYBYFLOAT but providing a
* negative value will work as expected.
*
* Time complexity: O(1)
* @see Jedis#incr(byte[])
* @see Jedis#decr(byte[])
* @see Jedis#decrBy(byte[], long)
* @param key the key to increment
* @param increment the value to increment by
* @return The value of key after the increment
*/
@Override
public double incrByFloat(final byte[] key, final double increment) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.incrByFloat(key, increment));
}
/**
* Increment the number stored at key by one. If the key does not exist or contains a value of a
* wrong type, set the key to the value of "0" before to perform the increment operation.
*
* INCR commands are limited to 64-bit signed integers.
*
* Note: this is actually a string operation, that is, in Redis there are not "integer" types.
* Simply the string stored at the key is parsed as a base 10 64-bit signed integer, incremented,
* and then converted back as a string.
*
* Time complexity: O(1)
* @see Jedis#incrBy(byte[], long)
* @see Jedis#decr(byte[])
* @see Jedis#decrBy(byte[], long)
* @param key
* @return The value of key after the increment
*/
@Override
public long incr(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.incr(key));
}
/**
* If the key already exists and is a string, this command appends the provided value at the end
* of the string. If the key does not exist it is created and set as an empty string, so APPEND
* will be very similar to SET in this special case.
*
* Time complexity: O(1). The amortized time complexity is O(1) assuming the appended value is
* small and the already present value is of any size, since the dynamic string library used by
* Redis will double the free space available on every reallocation.
* @param key
* @param value
* @return The total length of the string after the append operation
*/
@Override
public long append(final byte[] key, final byte[] value) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.append(key, value));
}
/**
* Return a subset of the string from offset start to offset end (both offsets are inclusive).
* Negative offsets can be used in order to provide an offset starting from the end of the string.
* So -1 means the last char, -2 the penultimate and so forth.
*
* The function handles out of range requests without raising an error, but just limiting the
* resulting range to the actual length of the string.
*
* Time complexity: O(start+n) (with start being the start index and n the total length of the
* requested range). Note that the lookup part of this command is O(1) so for small strings this
* is actually an O(1) command.
* @param key
* @param start
* @param end
* @return Bulk reply
*/
@Override
public byte[] substr(final byte[] key, final int start, final int end) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.substr(key, start, end));
}
/**
* Set the specified hash field to the specified value.
*
* If key does not exist, a new key holding a hash is created.
*
* Time complexity: O(1)
* @param key
* @param field
* @param value
* @return If the field already exists, and the HSET just produced an update of the value, 0 is
* returned, otherwise if a new field is created 1 is returned.
*/
@Override
public long hset(final byte[] key, final byte[] field, final byte[] value) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.hset(key, field, value));
}
@Override
public long hset(final byte[] key, final Map hash) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.hset(key, hash));
}
/**
* If key holds a hash, retrieve the value associated to the specified field.
*
* If the field is not found or the key does not exist, a special 'nil' value is returned.
*
* Time complexity: O(1)
* @param key
* @param field
* @return Bulk reply
*/
@Override
public byte[] hget(final byte[] key, final byte[] field) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.hget(key, field));
}
/**
* Set the specified hash field to the specified value if the field not exists. Time
* complexity: O(1)
* @param key
* @param field
* @param value
* @return If the field already exists, 0 is returned, otherwise if a new field is created 1 is
* returned.
*/
@Override
public long hsetnx(final byte[] key, final byte[] field, final byte[] value) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.hsetnx(key, field, value));
}
/**
* Set the respective fields to the respective values. HMSET replaces old values with new values.
*
* If key does not exist, a new key holding a hash is created.
*
* Time complexity: O(N) (with N being the number of fields)
* @param key
* @param hash
* @return OK
*/
@Override
public String hmset(final byte[] key, final Map hash) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.hmset(key, hash));
}
/**
* Retrieve the values associated to the specified fields.
*
* If some of the specified fields do not exist, nil values are returned. Non existing keys are
* considered like empty hashes.
*
* Time complexity: O(N) (with N being the number of fields)
* @param key
* @param fields
* @return A list of all the values associated with the specified fields, in the same order of the request
*/
@Override
public List hmget(final byte[] key, final byte[]... fields) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.hmget(key, fields));
}
/**
* Increment the number stored at field in the hash at key by value. If key does not exist, a new
* key holding a hash is created. If field does not exist or holds a string, the value is set to 0
* before applying the operation. Since the value argument is signed you can use this command to
* perform both increments and decrements.
*
* The range of values supported by HINCRBY is limited to 64-bit signed integers.
*
* Time complexity: O(1)
* @param key
* @param field
* @param value
* @return The value of key after the increment
*/
@Override
public long hincrBy(final byte[] key, final byte[] field, final long value) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.hincrBy(key, field, value));
}
/**
* Increment the number stored at field in the hash at key by a double precision floating point
* value. If key does not exist, a new key holding a hash is created. If field does not exist or
* holds a string, the value is set to 0 before applying the operation. Since the value argument
* is signed you can use this command to perform both increments and decrements.
*
* The range of values supported by HINCRBYFLOAT is limited to double precision floating point
* values.
*
* Time complexity: O(1)
* @param key
* @param field
* @param value
* @return The new value at field after the increment operation
*/
@Override
public double hincrByFloat(final byte[] key, final byte[] field, final double value) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.hincrByFloat(key, field, value));
}
/**
* Test for existence of a specified field in a hash. Time complexity: O(1)
* @param key
* @param field
* @return {@code true} if the hash stored at key contains the specified field, {@code false} if the key is
* not found or the field is not present.
*/
@Override
public boolean hexists(final byte[] key, final byte[] field) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.hexists(key, field));
}
/**
* Remove the specified field from an hash stored at key.
*
* Time complexity: O(1)
* @param key
* @param fields
* @return If the field was present in the hash it is deleted and 1 is returned, otherwise 0 is
* returned and no operation is performed.
*/
@Override
public long hdel(final byte[] key, final byte[]... fields) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.hdel(key, fields));
}
/**
* Return the number of items in a hash.
*
* Time complexity: O(1)
* @param key
* @return The number of entries (fields) contained in the hash stored at key. If the specified
* key does not exist, 0 is returned assuming an empty hash.
*/
@Override
public long hlen(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.hlen(key));
}
/**
* Return all the fields in a hash.
*
* Time complexity: O(N), where N is the total number of entries
* @param key
* @return All the fields names contained into a hash.
*/
@Override
public Set hkeys(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.hkeys(key));
}
/**
* Return all the values in a hash.
*
* Time complexity: O(N), where N is the total number of entries
* @param key
* @return All the fields values contained into a hash.
*/
@Override
public List hvals(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.hvals(key));
}
/**
* Return all the fields and associated values in a hash.
*
* Time complexity: O(N), where N is the total number of entries
* @param key
* @return All the fields and values contained into a hash.
*/
@Override
public Map hgetAll(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.hgetAll(key));
}
/**
* Get one random field from a hash.
*
* Time complexity: O(N), where N is the number of fields returned
* @param key
* @return one random field from a hash.
*/
@Override
public byte[] hrandfield(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.hrandfield(key));
}
/**
* Get multiple random fields from a hash.
*
* Time complexity: O(N), where N is the number of fields returned
* @param key
* @return Multiple random fields from a hash.
*/
@Override
public List hrandfield(final byte[] key, final long count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.hrandfield(key, count));
}
/**
* Get one or multiple random fields with values from a hash.
*
* Time complexity: O(N), where N is the number of fields returned
* @param key
* @return One or multiple random fields with values from a hash.
*/
@Override
public List> hrandfieldWithValues(final byte[] key, final long count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.hrandfieldWithValues(key, count));
}
/**
* Add the string value to the head (LPUSH) or tail (RPUSH) of the list stored at key. If the key
* does not exist an empty list is created just before the append operation. If the key exists but
* is not a List an error is returned.
*
* Time complexity: O(1)
* @param key
* @param strings
* @return The number of elements inside the list after the push operation
*/
@Override
public long rpush(final byte[] key, final byte[]... strings) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.rpush(key, strings));
}
/**
* Add the string value to the head (LPUSH) or tail (RPUSH) of the list stored at key. If the key
* does not exist an empty list is created just before the append operation. If the key exists but
* is not a List an error is returned.
*
* Time complexity: O(1)
* @param key
* @param strings
* @return The number of elements inside the list after the push operation
*/
@Override
public long lpush(final byte[] key, final byte[]... strings) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.lpush(key, strings));
}
/**
* Return the length of the list stored at the specified key. If the key does not exist zero is
* returned (the same behaviour as for empty lists). If the value stored at key is not a list an
* error is returned.
*
* Time complexity: O(1)
* @param key
* @return The length of the list
*/
@Override
public long llen(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.llen(key));
}
/**
* Return the specified elements of the list stored at the specified key. Start and end are
* zero-based indexes. 0 is the first element of the list (the list head), 1 the next element and
* so on.
*
* For example LRANGE foobar 0 2 will return the first three elements of the list.
*
* start and end can also be negative numbers indicating offsets from the end of the list. For
* example -1 is the last element of the list, -2 the penultimate element and so on.
*
* Consistency with range functions in various programming languages
*
* Note that if you have a list of numbers from 0 to 100, LRANGE 0 10 will return 11 elements,
* that is, rightmost item is included. This may or may not be consistent with behavior of
* range-related functions in your programming language of choice (think Ruby's Range.new,
* Array#slice or Python's range() function).
*
* LRANGE behavior is consistent with one of Tcl.
*
* Out-of-range indexes
*
* Indexes out of range will not produce an error: if start is over the end of the list, or start
* > end, an empty list is returned. If end is over the end of the list Redis will threat it
* just like the last element of the list.
*
* Time complexity: O(start+n) (with n being the length of the range and start being the start
* offset)
* @param key
* @param start
* @param stop
* @return A list of elements in the specified range
*/
@Override
public List lrange(final byte[] key, final long start, final long stop) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.lrange(key, start, stop));
}
/**
* Trim an existing list so that it will contain only the specified range of elements specified.
* Start and end are zero-based indexes. 0 is the first element of the list (the list head), 1 the
* next element and so on.
*
* For example LTRIM foobar 0 2 will modify the list stored at foobar key so that only the first
* three elements of the list will remain.
*
* start and end can also be negative numbers indicating offsets from the end of the list. For
* example -1 is the last element of the list, -2 the penultimate element and so on.
*
* Indexes out of range will not produce an error: if start is over the end of the list, or start
* > end, an empty list is left as value. If end over the end of the list Redis will threat it
* just like the last element of the list.
*
* Hint: the obvious use of LTRIM is together with LPUSH/RPUSH. For example:
*
* {@code lpush("mylist", "someelement"); ltrim("mylist", 0, 99); * }
*
* The above two commands will push elements in the list taking care that the list will not grow
* without limits. This is very useful when using Redis to store logs for example. It is important
* to note that when used in this way LTRIM is an O(1) operation because in the average case just
* one element is removed from the tail of the list.
*
* Time complexity: O(n) (with n being len of list - len of range)
* @param key
* @param start
* @param stop
* @return OK
*/
@Override
public String ltrim(final byte[] key, final long start, final long stop) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.ltrim(key, start, stop));
}
/**
* Return the specified element of the list stored at the specified key. 0 is the first element, 1
* the second and so on. Negative indexes are supported, for example -1 is the last element, -2
* the penultimate and so on.
*
* If the value stored at key is not of list type an error is returned. If the index is out of
* range a 'nil' reply is returned.
*
* Note that even if the average time complexity is O(n) asking for the first or the last element
* of the list is O(1).
*
* Time complexity: O(n) (with n being the length of the list)
* @param key
* @param index
* @return The requested element
*/
@Override
public byte[] lindex(final byte[] key, final long index) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.lindex(key, index));
}
/**
* Set a new value as the element at index position of the List at key.
*
* Out of range indexes will generate an error.
*
* Similarly to other list commands accepting indexes, the index can be negative to access
* elements starting from the end of the list. So -1 is the last element, -2 is the penultimate,
* and so forth.
*
* Time complexity:
*
* O(N) (with N being the length of the list), setting the first or last elements of the list is
* O(1).
* @see Jedis#lindex(byte[], long)
* @param key
* @param index
* @param value
* @return OK
*/
@Override
public String lset(final byte[] key, final long index, final byte[] value) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.lset(key, index, value));
}
/**
* Remove the first count occurrences of the value element from the list. If count is zero all the
* elements are removed. If count is negative elements are removed from tail to head, instead to
* go from head to tail that is the normal behaviour. So for example LREM with count -2 and hello
* as value to remove against the list (a,b,c,hello,x,hello,hello) will leave the list
* (a,b,c,hello,x). The number of removed elements is returned as an integer, see below for more
* information about the returned value. Note that non existing keys are considered like empty
* lists by LREM, so LREM against non existing keys will always return 0.
*
* Time complexity: O(N) (with N being the length of the list)
* @param key
* @param count
* @param value
* @return The number of removed elements if the operation succeeded
*/
@Override
public long lrem(final byte[] key, final long count, final byte[] value) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.lrem(key, count, value));
}
/**
* Atomically return and remove the first (LPOP) or last (RPOP) element of the list. For example
* if the list contains the elements "a","b","c" LPOP will return "a" and the list will become
* "b","c".
*
* If the key does not exist or the list is already empty the special value 'nil' is returned.
* @see Jedis#rpop(byte[])
* @param key
* @return Bulk reply
*/
@Override
public byte[] lpop(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.lpop(key));
}
@Override
public List lpop(final byte[] key, final int count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.lpop(key, count));
}
/**
* Returns the index of the first matching element inside a redis list. If the element is found,
* its index (the zero-based position in the list) is returned. Otherwise, if no match is found,
* 'nil' is returned.
*
* Time complexity: O(N) where N is the number of elements in the list
* @see Jedis#lpos(byte[], byte[])
* @param key
* @param element
* @return The index of first matching element in the list. Value will
* be 'nil' when the element is not present in the list.
*/
@Override
public Long lpos(final byte[] key, final byte[] element) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.lpos(key, element));
}
/**
* In case there are multiple matches Rank option specifies the "rank" of the element to return.
* A rank of 1 returns the first match, 2 to return the second match, and so forth.
* If list `foo` has elements ("a","b","c","1","2","3","c","c"), The function call to get the
* index of second occurrence of "c" will be as follows lpos("foo","c", LPosParams.lPosParams().rank(2)).
*
* Maxlen option compares the element provided only with a given maximum number of list items.
* A value of 1000 will make sure that the command performs only 1000 comparisons. The
* comparison is made for the first part or the last part depending on the fact we use a positive or
* negative rank.
* Following is how we could use the Maxlen option lpos("foo", "b", LPosParams.lPosParams().rank(1).maxlen(2)).
* @see Jedis#lpos(byte[], byte[], LPosParams)
* @param key
* @param element
* @param params
* @return The index of first matching element in the list. Value will be 'nil' when the element
* is not present in the list
*/
@Override
public Long lpos(final byte[] key, final byte[] element, final LPosParams params) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.lpos(key, element, params));
}
/**
* Count will return list of position of all the first N matching elements. It is possible to
* specify 0 as the number of matches, as a way to tell the command we want all the matches
* found returned as an array of indexes. When count is used and no match is found, an empty list
* is returned.
*
* Time complexity: O(N) where N is the number of elements in the list
* @see Jedis#lpos(byte[], byte[], LPosParams, long)
* @param key
* @param element
* @param params
* @param count
* @return A list containing position of the matching elements inside the list
*/
@Override
public List lpos(final byte[] key, final byte[] element, final LPosParams params,
final long count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.lpos(key, element, params, count));
}
/**
* Atomically return and remove the first (LPOP) or last (RPOP) element of the list. For example
* if the list contains the elements "a","b","c" LPOP will return "a" and the list will become
* "b","c".
*
* If the key does not exist or the list is already empty the special value 'nil' is returned.
* @see Jedis#lpop(byte[])
* @param key
* @return Bulk reply
*/
@Override
public byte[] rpop(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.rpop(key));
}
@Override
public List rpop(final byte[] key, final int count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.rpop(key, count));
}
/**
* Atomically return and remove the last (tail) element of the srckey list, and push the element
* as the first (head) element of the dstkey list. For example if the source list contains the
* elements "a","b","c" and the destination list contains the elements "foo","bar" after an
* RPOPLPUSH command the content of the two lists will be "a","b" and "c","foo","bar".
*
* If the key does not exist or the list is already empty the special value 'nil' is returned. If
* the srckey and dstkey are the same the operation is equivalent to removing the last element
* from the list and pushing it as first element of the list, so it's a "list rotation" command.
*
* Time complexity: O(1)
* @param srckey
* @param dstkey
* @return Bulk reply
*/
@Override
public byte[] rpoplpush(final byte[] srckey, final byte[] dstkey) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.rpoplpush(srckey, dstkey));
}
/**
* Add the specified member to the set value stored at key. If member is already a member of the
* set no operation is performed. If key does not exist a new set with the specified member as
* sole member is created. If the key exists but does not hold a set value an error is returned.
*
* Time complexity O(1)
* @param key
* @param members
* @return The number of elements that were added to the set, not including all the elements already
* present in the set
*/
@Override
public long sadd(final byte[] key, final byte[]... members) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.sadd(key, members));
}
/**
* Return all the members (elements) of the set value stored at key. This is just syntax glue for
* {@link Jedis#sinter(byte[][])} SINTER}.
*
* Time complexity O(N)
* @param key the key of the set
* @return All elements of the set
*/
@Override
public Set smembers(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.smembers(key));
}
/**
* Remove the specified member from the set value stored at key. If member was not a member of the
* set no operation is performed. If key does not hold a set value an error is returned.
*
* Time complexity O(1)
* @param key the key of the set
* @param members the set member to remove
* @return The number of members that were removed from the set, not including non-existing members
*/
@Override
public long srem(final byte[] key, final byte[]... members) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.srem(key, members));
}
/**
* Remove a random element from a Set returning it as return value. If the Set is empty or the key
* does not exist, a nil object is returned.
*
* The {@link Jedis#srandmember(byte[])} command does a similar work but the returned element is
* not removed from the Set.
*
* Time complexity O(1)
* @param key
* @return The removed member, or nil when key does not exist
*/
@Override
public byte[] spop(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.spop(key));
}
@Override
public Set spop(final byte[] key, final long count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.spop(key, count));
}
/**
* Move the specified member from the set at srckey to the set at dstkey. This operation is
* atomic, in every given moment the element will appear to be in the source or destination set
* for accessing clients.
*
* If the source set does not exist or does not contain the specified element no operation is
* performed and zero is returned, otherwise the element is removed from the source set and added
* to the destination set. On success one is returned, even if the element was already present in
* the destination set.
*
* An error is raised if the source or destination keys contain a non Set value.
*
* Time complexity O(1)
* @param srckey
* @param dstkey
* @param member
* @return 1 if the element was moved, 0 if no operation was performed
*/
@Override
public long smove(final byte[] srckey, final byte[] dstkey, final byte[] member) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.smove(srckey, dstkey, member));
}
/**
* Return the set cardinality (number of elements). If the key does not exist 0 is returned, like
* for empty sets.
* @param key
* @return The cardinality (number of elements) of the set
*/
@Override
public long scard(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.scard(key));
}
/**
* Return true if member is a member of the set stored at key, otherwise false is returned.
*
* Time complexity O(1)
* @param key
* @param member
* @return {@code true} if the element is a member of the set, {@code false} otherwise
*/
@Override
public boolean sismember(final byte[] key, final byte[] member) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.sismember(key, member));
}
/**
* Returns whether each member is a member of the set stored at key.
*
* Time complexity O(N) where N is the number of elements being checked for membership
* @param key
* @param members
* @return List representing the membership of the given elements, in the same order as they are requested
*/
@Override
public List smismember(final byte[] key, final byte[]... members) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.smismember(key, members));
}
/**
* Return the members of a set resulting from the intersection of all the sets hold at the
* specified keys. Like in {@link Jedis#lrange(byte[], long, long)} LRANGE} the result is sent to
* the connection as a multi-bulk reply (see the protocol specification for more information). If
* just a single key is specified, then this command produces the same result as
* {@link Jedis#smembers(byte[]) SMEMBERS}. Actually SMEMBERS is just syntax sugar for SINTER.
*
* Non existing keys are considered like empty sets, so if one of the keys is missing an empty set
* is returned (since the intersection with an empty set always is an empty set).
*
* Time complexity O(N*M) worst case where N is the cardinality of the smallest set and M the
* number of sets
* @param keys
* @return A set with members of the resulting set
*/
@Override
public Set sinter(final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.sinter(keys));
}
/**
* This command works exactly like {@link Jedis#sinter(byte[][]) SINTER} but instead of being
* returned the resulting set is stored as dstkey.
*
* Time complexity O(N*M) worst case where N is the cardinality of the smallest set and M the
* number of sets
* @param dstkey
* @param keys
* @return The number of elements in the resulting set
*/
@Override
public long sinterstore(final byte[] dstkey, final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.sinterstore(dstkey, keys));
}
/**
* This command works exactly like {@link Jedis#sinter(byte[][]) SINTER} but instead of returning
* the result set, it returns just the cardinality of the result. LIMIT defaults to 0 and means unlimited
*
* Time complexity O(N*M) worst case where N is the cardinality of the smallest
* @param keys
* @return The cardinality of the set which would result from the intersection of all the given sets
*/
@Override
public long sintercard(byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.sintercard(keys));
}
/**
* This command works exactly like {@link Jedis#sinter(byte[][]) SINTER} but instead of returning
* the result set, it returns just the cardinality of the result.
*
* Time complexity O(N*M) worst case where N is the cardinality of the smallest
* @param limit If the intersection cardinality reaches limit partway through the computation,
* the algorithm will exit and yield limit as the cardinality.
* @param keys
* @return The cardinality of the set which would result from the intersection of all the given sets
*/
@Override
public long sintercard(int limit, byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.sintercard(limit, keys));
}
/**
* Return the members of a set resulting from the union of all the sets hold at the specified
* keys. Like in {@link Jedis#lrange(byte[], long, long)} LRANGE} the result is sent to the
* connection as a multi-bulk reply (see the protocol specification for more information). If just
* a single key is specified, then this command produces the same result as
* {@link Jedis#smembers(byte[]) SMEMBERS}.
*
* Non existing keys are considered like empty sets.
*
* Time complexity O(N) where N is the total number of elements in all the provided sets
* @param keys
* @return A set with members of the resulting set
*/
@Override
public Set sunion(final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.sunion(keys));
}
/**
* This command works exactly like {@link Jedis#sunion(byte[][]) SUNION} but instead of being
* returned the resulting set is stored as dstkey. Any existing value in dstkey will be
* over-written.
*
* Time complexity O(N) where N is the total number of elements in all the provided sets
* @param dstkey
* @param keys
* @return The number of elements in the resulting set
*/
@Override
public long sunionstore(final byte[] dstkey, final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.sunionstore(dstkey, keys));
}
/**
* Return the difference between the Set stored at key1 and all the Sets key2, ..., keyN
*
* Example:
*
*
* key1 = [x, a, b, c]
* key2 = [c]
* key3 = [a, d]
* SDIFF key1,key2,key3 => [x, b]
*
*
* Non existing keys are considered like empty sets.
*
* Time complexity:
*
* O(N) with N being the total number of elements of all the sets
* @param keys
* @return A set with members of the resulting set
*/
@Override
public Set sdiff(final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.sdiff(keys));
}
/**
* This command works exactly like {@link Jedis#sdiff(byte[][]) SDIFF} but instead of being returned
* the resulting set is stored in dstkey.
* @param dstkey
* @param keys
* @return The number of elements in the resulting set
*/
@Override
public long sdiffstore(final byte[] dstkey, final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.sdiffstore(dstkey, keys));
}
/**
* Return a random element from a Set, without removing the element. If the Set is empty or the
* key does not exist, a nil object is returned.
*
* The SPOP command does a similar work but the returned element is popped (removed) from the Set.
*
* Time complexity O(1)
* @param key
* @return The randomly selected element
*/
@Override
public byte[] srandmember(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.srandmember(key));
}
@Override
public List srandmember(final byte[] key, final int count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.srandmember(key, count));
}
/**
* Add the specified member having the specified score to the sorted set stored at key. If member
* is already a member of the sorted set the score is updated, and the element reinserted in the
* right position to ensure sorting. If key does not exist a new sorted set with the specified
* member as sole member is created. If the key exists but does not hold a sorted set value an
* error is returned.
*
* The score value can be the string representation of a double precision floating point number.
*
* Time complexity O(log(N)) with N being the number of elements in the sorted set
* @param key
* @param score
* @param member
* @return 1 if the new element was added, 0 if the element was already a member of the sorted
* set and the score was updated
*/
@Override
public long zadd(final byte[] key, final double score, final byte[] member) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zadd(key, score, member));
}
@Override
public long zadd(final byte[] key, final double score, final byte[] member,
final ZAddParams params) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zadd(key, score, member, params));
}
@Override
public long zadd(final byte[] key, final Map scoreMembers) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zadd(key, scoreMembers));
}
@Override
public long zadd(final byte[] key, final Map scoreMembers, final ZAddParams params) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zadd(key, scoreMembers, params));
}
@Override
public Double zaddIncr(final byte[] key, final double score, final byte[] member, final ZAddParams params) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zaddIncr(key, score, member, params));
}
@Override
public List zrange(final byte[] key, final long start, final long stop) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrange(key, start, stop));
}
/**
* Remove the specified member from the sorted set value stored at key. If member was not a member
* of the set no operation is performed. If key does not not hold a set value an error is
* returned.
*
* Time complexity O(log(N)) with N being the number of elements in the sorted set
* @param key
* @param members
* @return 1 if the new element was removed, 0 if the new element was not a member of the set
*/
@Override
public long zrem(final byte[] key, final byte[]... members) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrem(key, members));
}
/**
* If member already exists in the sorted set adds the increment to its score and updates the
* position of the element in the sorted set accordingly. If member does not already exist in the
* sorted set it is added with increment as score (that is, like if the previous score was
* virtually zero). If key does not exist a new sorted set with the specified member as sole
* member is created. If the key exists but does not hold a sorted set value an error is returned.
*
* The score value can be the string representation of a double precision floating point number.
* It's possible to provide a negative value to perform a decrement.
*
* For an introduction to sorted sets check the Introduction to Redis data types page.
*
* Time complexity O(log(N)) with N being the number of elements in the sorted set
* @param key
* @param increment
* @param member
* @return The new score
*/
@Override
public double zincrby(final byte[] key, final double increment, final byte[] member) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zincrby(key, increment, member));
}
@Override
public Double zincrby(final byte[] key, final double increment, final byte[] member,
final ZIncrByParams params) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zincrby(key, increment, member, params));
}
/**
* Return the rank (or index) or member in the sorted set at key, with scores being ordered from
* low to high.
*
* When the given member does not exist in the sorted set, the special value 'nil' is returned.
* The returned rank (or index) of the member is 0-based for both commands.
*
* Time complexity:
*
* O(log(N))
* @see Jedis#zrevrank(byte[], byte[])
* @param key
* @param member
* @return The element as an integer if the element exists. A 'nil' bulk reply if there is no such element
*/
@Override
public Long zrank(final byte[] key, final byte[] member) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrank(key, member));
}
/**
* Return the rank (or index) or member in the sorted set at key, with scores being ordered from
* high to low.
*
* When the given member does not exist in the sorted set, the special value 'nil' is returned.
* The returned rank (or index) of the member is 0-based for both commands.
*
* Time complexity:
*
* O(log(N))
* @see Jedis#zrank(byte[], byte[])
* @param key
* @param member
* @return The element as an integer if the element exists. A 'nil' bulk reply if there is no such element.
*/
@Override
public Long zrevrank(final byte[] key, final byte[] member) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrevrank(key, member));
}
/**
* Returns the rank and the score of member in the sorted set stored at key, with the scores
* ordered from low to high.
* @param key the key
* @param member the member
* @return the KeyValue contains rank and score.
*/
@Override
public KeyValue zrankWithScore(byte[] key, byte[] member) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrankWithScore(key, member));
}
/**
* Returns the rank and the score of member in the sorted set stored at key, with the scores
* ordered from high to low.
* @param key the key
* @param member the member
* @return the KeyValue contains rank and score.
*/
@Override
public KeyValue zrevrankWithScore(byte[] key, byte[] member) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrevrankWithScore(key, member));
}
@Override
public List zrevrange(final byte[] key, final long start, final long stop) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrevrange(key, start, stop));
}
@Override
public List zrangeWithScores(final byte[] key, final long start, final long stop) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrangeWithScores(key, start, stop));
}
@Override
public List zrevrangeWithScores(final byte[] key, final long start, final long stop) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrevrangeWithScores(key, start, stop));
}
@Override
public List zrange(byte[] key, ZRangeParams zRangeParams) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrange(key, zRangeParams));
}
@Override
public List zrangeWithScores(byte[] key, ZRangeParams zRangeParams) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrangeWithScores(key, zRangeParams));
}
@Override
public long zrangestore(byte[] dest, byte[] src, ZRangeParams zRangeParams) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrangestore(dest, src, zRangeParams));
}
@Override
public byte[] zrandmember(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrandmember(key));
}
@Override
public List zrandmember(final byte[] key, final long count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrandmember(key, count));
}
@Override
public List zrandmemberWithScores(final byte[] key, final long count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrandmemberWithScores(key, count));
}
/**
* Return the sorted set cardinality (number of elements). If the key does not exist 0 is
* returned, like for empty sorted sets.
*
* Time complexity O(1)
* @param key
* @return The cardinality (number of elements) of the set as an integer.
*/
@Override
public long zcard(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zcard(key));
}
/**
* Return the score of the specified element of the sorted set at key. If the specified element
* does not exist in the sorted set, or the key does not exist at all, a special 'nil' value is
* returned.
*
* Time complexity: O(1)
* @param key
* @param member
* @return The score
*/
@Override
public Double zscore(final byte[] key, final byte[] member) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zscore(key, member));
}
/**
* Returns the scores associated with the specified members in the sorted set stored at key.
* For every member that does not exist in the sorted set, a nil value is returned.
*
* Time complexity: O(N) where N is the number of members being requested.
* @param key
* @param members
* @return The scores
*/
@Override
public List zmscore(final byte[] key, final byte[]... members) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zmscore(key, members));
}
@Override
public Tuple zpopmax(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zpopmax(key));
}
@Override
public List zpopmax(final byte[] key, final int count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zpopmax(key, count));
}
@Override
public Tuple zpopmin(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zpopmin(key));
}
@Override
public List zpopmin(final byte[] key, final int count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zpopmin(key, count));
}
public String watch(final byte[]... keys) {
checkIsInMultiOrPipeline();
connection.sendCommand(WATCH, keys);
// return connection.getStatusCodeReply();
String status = connection.getStatusCodeReply();
isInWatch = true;
return status;
}
public String unwatch() {
checkIsInMultiOrPipeline();
connection.sendCommand(UNWATCH);
return connection.getStatusCodeReply();
}
/**
* Sort a Set or a List.
*
* Sort the elements contained in the List, Set, or Sorted Set value at key. By default sorting is
* numeric with elements being compared as double precision floating point numbers. This is the
* simplest form of SORT.
* @see Jedis#sort(byte[], byte[])
* @see Jedis#sort(byte[], SortingParams)
* @see Jedis#sort(byte[], SortingParams, byte[])
* @param key
* @return Assuming the Set/List at key contains a list of numbers, the return value will be the
* list of numbers ordered from the smallest to the biggest number.
*/
@Override
public List sort(final byte[] key) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.sort(key));
}
/**
* Sort a Set or a List accordingly to the specified parameters.
*
* examples:
*
* Given are the following sets and key/values:
*
*
* x = [1, 2, 3]
* y = [a, b, c]
*
* k1 = z
* k2 = y
* k3 = x
*
* w1 = 9
* w2 = 8
* w3 = 7
*
*
* Sort Order:
*
*
* sort(x) or sort(x, sp.asc())
* -> [1, 2, 3]
*
* sort(x, sp.desc())
* -> [3, 2, 1]
*
* sort(y)
* -> [c, a, b]
*
* sort(y, sp.alpha())
* -> [a, b, c]
*
* sort(y, sp.alpha().desc())
* -> [c, a, b]
*
*
* Limit (e.g. for Pagination):
*
*
* sort(x, sp.limit(0, 2))
* -> [1, 2]
*
* sort(y, sp.alpha().desc().limit(1, 2))
* -> [b, a]
*
*
* Sorting by external keys:
*
*
* sort(x, sb.by(w*))
* -> [3, 2, 1]
*
* sort(x, sb.by(w*).desc())
* -> [1, 2, 3]
*
*
* Getting external keys:
*
*
* sort(x, sp.by(w*).get(k*))
* -> [x, y, z]
*
* sort(x, sp.by(w*).get(#).get(k*))
* -> [3, x, 2, y, 1, z]
*
* @see Jedis#sort(byte[])
* @see Jedis#sort(byte[], SortingParams, byte[])
* @param key
* @param sortingParams
* @return a list of sorted elements.
*/
@Override
public List sort(final byte[] key, final SortingParams sortingParams) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.sort(key, sortingParams));
}
/**
* Sort a Set or a List accordingly to the specified parameters and store the result at dstkey.
* @see Jedis#sort(byte[], SortingParams)
* @see Jedis#sort(byte[])
* @see Jedis#sort(byte[], byte[])
* @param key
* @param sortingParams
* @param dstkey
* @return The number of elements of the list at dstkey.
*/
@Override
public long sort(final byte[] key, final SortingParams sortingParams, final byte[] dstkey) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.sort(key, sortingParams, dstkey));
}
/**
* Sort a Set or a List and Store the Result at dstkey.
*
* Sort the elements contained in the List, Set, or Sorted Set value at key and store the result
* at dstkey. By default sorting is numeric with elements being compared as double precision
* floating point numbers. This is the simplest form of SORT.
* @see Jedis#sort(byte[])
* @see Jedis#sort(byte[], SortingParams)
* @see Jedis#sort(byte[], SortingParams, byte[])
* @param key
* @param dstkey
* @return The number of elements of the list at dstkey.
*/
@Override
public long sort(final byte[] key, final byte[] dstkey) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.sort(key, dstkey));
}
@Override
public List sortReadonly(byte[] key, SortingParams sortingParams) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.sortReadonly(key, sortingParams));
}
/**
* Pop an element from a list, push it to another list and return it
* @param srcKey
* @param dstKey
* @param from
* @param to
* @return The element being popped and pushed
*/
@Override
public byte[] lmove(byte[] srcKey, byte[] dstKey, ListDirection from, ListDirection to) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.lmove(srcKey, dstKey, from, to));
}
/**
* Pop an element from a list, push it to another list and return it; or block until one is available
* @param srcKey
* @param dstKey
* @param from
* @param to
* @param timeout
* @return The element being popped and pushed
*/
@Override
public byte[] blmove(byte[] srcKey, byte[] dstKey, ListDirection from, ListDirection to, double timeout) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.blmove(srcKey, dstKey, from, to, timeout));
}
/**
* BLPOP (and BRPOP) is a blocking list pop primitive. You can see this commands as blocking
* versions of LPOP and RPOP able to block if the specified keys don't exist or contain empty
* lists.
*
* The following is a description of the exact semantic. We describe BLPOP but the two commands
* are identical, the only difference is that BLPOP pops the element from the left (head) of the
* list, and BRPOP pops from the right (tail).
*
* Non blocking behavior
*
* When BLPOP is called, if at least one of the specified keys contain a non empty list, an
* element is popped from the head of the list and returned to the caller together with the name
* of the key (BLPOP returns a two elements array, the first element is the key, the second the
* popped value).
*
* Keys are scanned from left to right, so for instance if you issue BLPOP list1 list2 list3 0
* against a dataset where list1 does not exist but list2 and list3 contain non empty lists, BLPOP
* guarantees to return an element from the list stored at list2 (since it is the first non empty
* list starting from the left).
*
* Blocking behavior
*
* If none of the specified keys exist or contain non empty lists, BLPOP blocks until some other
* connection performs a LPUSH or an RPUSH operation against one of the lists.
*
* Once new data is present on one of the lists, the connection finally returns with the name of the
* key unblocking it and the popped value.
*
* When blocking, if a non-zero timeout is specified, the connection will unblock returning a nil
* special value if the specified amount of seconds passed without a push operation against at
* least one of the specified keys.
*
* The timeout argument is interpreted as an integer value. A timeout of zero means instead to
* block forever.
*
* Multiple clients blocking for the same keys
*
* Multiple clients can block for the same key. They are put into a queue, so the first to be
* served will be the one that started to wait earlier, in a first-blpopping first-served fashion.
*
* blocking POP inside a MULTI/EXEC transaction
*
* BLPOP and BRPOP can be used with pipelining (sending multiple commands and reading the replies
* in batch), but it does not make sense to use BLPOP or BRPOP inside a MULTI/EXEC block (a Redis
* transaction).
*
* The behavior of BLPOP inside MULTI/EXEC when the list is empty is to return a multi-bulk nil
* reply, exactly what happens when the timeout is reached. If you like science fiction, think at
* it like if inside MULTI/EXEC the time will flow at infinite speed :)
*
* Time complexity: O(1)
* @param timeout
* @param keys
* @return BLPOP returns a two-elements array via a multi bulk reply in order to return both the
* unblocking key and the popped value.
*
When a non-zero timeout is specified, and the BLPOP operation timed out, the return
value is a nil multi bulk reply. Most connection values will return false or nil
accordingly to the programming language used.
*/
@Override
public List blpop(final int timeout, final byte[]... keys) {
return connection.executeCommand(commandObjects.blpop(timeout, keys));
}
@Override
public KeyValue blpop(final double timeout, final byte[]... keys) {
return connection.executeCommand(commandObjects.blpop(timeout, keys));
}
/**
* BLPOP (and BRPOP) is a blocking list pop primitive. You can see this commands as blocking
* versions of LPOP and RPOP able to block if the specified keys don't exist or contain empty
* lists.
*
* The following is a description of the exact semantic. We describe BLPOP but the two commands
* are identical, the only difference is that BLPOP pops the element from the left (head) of the
* list, and BRPOP pops from the right (tail).
*
* Non blocking behavior
*
* When BLPOP is called, if at least one of the specified keys contain a non empty list, an
* element is popped from the head of the list and returned to the caller together with the name
* of the key (BLPOP returns a two elements array, the first element is the key, the second the
* popped value).
*
* Keys are scanned from left to right, so for instance if you issue BLPOP list1 list2 list3 0
* against a dataset where list1 does not exist but list2 and list3 contain non empty lists, BLPOP
* guarantees to return an element from the list stored at list2 (since it is the first non empty
* list starting from the left).
*
* Blocking behavior
*
* If none of the specified keys exist or contain non empty lists, BLPOP blocks until some other
* connection performs a LPUSH or an RPUSH operation against one of the lists.
*
* Once new data is present on one of the lists, the connection finally returns with the name of the
* key unblocking it and the popped value.
*
* When blocking, if a non-zero timeout is specified, the connection will unblock returning a nil
* special value if the specified amount of seconds passed without a push operation against at
* least one of the specified keys.
*
* The timeout argument is interpreted as an integer value. A timeout of zero means instead to
* block forever.
*
* Multiple clients blocking for the same keys
*
* Multiple clients can block for the same key. They are put into a queue, so the first to be
* served will be the one that started to wait earlier, in a first-blpopping first-served fashion.
*
* blocking POP inside a MULTI/EXEC transaction
*
* BLPOP and BRPOP can be used with pipelining (sending multiple commands and reading the replies
* in batch), but it does not make sense to use BLPOP or BRPOP inside a MULTI/EXEC block (a Redis
* transaction).
*
* The behavior of BLPOP inside MULTI/EXEC when the list is empty is to return a multi-bulk nil
* reply, exactly what happens when the timeout is reached. If you like science fiction, think at
* it like if inside MULTI/EXEC the time will flow at infinite speed :)
*
* Time complexity: O(1)
* @param timeout
* @param keys
* @return BLPOP returns a two-elements array via a multi bulk reply in order to return both the
* unblocking key and the popped value.
*
When a non-zero timeout is specified, and the BLPOP operation timed out, the return
value is a nil multi bulk reply. Most connection values will return false or nil
accordingly to the programming language used.
*/
@Override
public List brpop(final int timeout, final byte[]... keys) {
return connection.executeCommand(commandObjects.brpop(timeout, keys));
}
@Override
public KeyValue brpop(final double timeout, final byte[]... keys) {
return connection.executeCommand(commandObjects.brpop(timeout, keys));
}
@Override
public KeyValue> lmpop(ListDirection direction, byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.lmpop(direction, keys));
}
@Override
public KeyValue> lmpop(ListDirection direction, int count, byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.lmpop(direction, count, keys));
}
@Override
public KeyValue> blmpop(double timeout, ListDirection direction, byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.blmpop(timeout, direction, keys));
}
@Override
public KeyValue> blmpop(double timeout, ListDirection direction, int count, byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.blmpop(timeout, direction, count, keys));
}
@Override
public KeyValue bzpopmax(final double timeout, final byte[]... keys) {
return connection.executeCommand(commandObjects.bzpopmax(timeout, keys));
}
@Override
public KeyValue bzpopmin(final double timeout, final byte[]... keys) {
return connection.executeCommand(commandObjects.bzpopmin(timeout, keys));
}
/**
* Request for authentication in a password protected Redis server. A Redis server can be
* instructed to require a password before to allow clients to issue commands. This is done using
* the requirepass directive in the Redis configuration file. If the password given by the connection
* is correct the server replies with an OK status code reply and starts accepting commands from
* the connection. Otherwise, an error is returned and the clients needs to try a new password. Note
* that for the high performance nature of Redis it is possible to try a lot of passwords in
* parallel in very short time, so make sure to generate a strong and very long password so that
* this attack is infeasible.
* @param password
* @return OK
*/
@Override
public String auth(final String password) {
checkIsInMultiOrPipeline();
connection.sendCommand(Command.AUTH, password);
return connection.getStatusCodeReply();
}
/**
* Request for authentication with a Redis Server that is using ACL where user are authenticated with
* username and password.
* See https://redis.io/topics/acl
* @param user
* @param password
* @return OK
*/
@Override
public String auth(final String user, final String password) {
checkIsInMultiOrPipeline();
connection.sendCommand(Command.AUTH, user, password);
return connection.getStatusCodeReply();
}
@Override
public long zcount(final byte[] key, final double min, final double max) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zcount(key, min, max));
}
@Override
public long zcount(final byte[] key, final byte[] min, final byte[] max) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zcount(key, min, max));
}
@Override
public List zdiff(final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zdiff(keys));
}
@Override
public List zdiffWithScores(final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zdiffWithScores(keys));
}
@Override
@Deprecated
public long zdiffStore(final byte[] dstkey, final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zdiffStore(dstkey, keys));
}
@Override
public long zdiffstore(final byte[] dstkey, final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zdiffstore(dstkey, keys));
}
/**
* Return the all the elements in the sorted set at key with a score between min and max
* (including elements with score equal to min or max).
*
* The elements having the same score are returned sorted lexicographically as ASCII strings (this
* follows from a property of Redis sorted sets and does not involve further computation).
*
* Using the optional {@link Jedis#zrangeByScore(byte[], double, double, int, int) LIMIT} it is
* possible to get only a range of the matching elements in an SQL-alike way. Note that if the
* offset is large the commands needs to traverse the list for offset elements and this adds up to
* the O(M) figure.
*
* The {@link Jedis#zcount(byte[], double, double) ZCOUNT} command is similar to
* {@link Jedis#zrangeByScore(byte[], double, double) ZRANGEBYSCORE} but instead of returning the
* actual elements in the specified interval, it just returns the number of matching elements.
*
* Exclusive intervals and infinity
*
* min and max can be -inf and +inf, so that you are not required to know what's the greatest or
* smallest element in order to take, for instance, elements "up to a given value".
*
* Also while the interval is for default closed (inclusive) it is possible to specify open
* intervals prefixing the score with a "(" character, so for instance:
*
* {@code ZRANGEBYSCORE zset (1.3 5}
*
* Will return all the values with score > 1.3 and <= 5, while for instance:
*
* {@code ZRANGEBYSCORE zset (5 (10}
*
* Will return all the values with score > 5 and < 10 (5 and 10 excluded).
*
* Time complexity:
*
* O(log(N))+O(M) with N being the number of elements in the sorted set and M the number of
* elements returned by the command, so if M is constant (for instance you always ask for the
* first ten elements with LIMIT) you can consider it O(log(N))
* @see Jedis#zrangeByScore(byte[], double, double)
* @see Jedis#zrangeByScore(byte[], double, double, int, int)
* @see Jedis#zrangeByScoreWithScores(byte[], double, double)
* @see Jedis#zrangeByScoreWithScores(byte[], double, double, int, int)
* @see Jedis#zcount(byte[], double, double)
* @param key
* @param min
* @param max
* @return A list of elements in the specified score range
*/
@Override
public List zrangeByScore(final byte[] key, final double min, final double max) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrangeByScore(key, min, max));
}
@Override
public List zrangeByScore(final byte[] key, final byte[] min, final byte[] max) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrangeByScore(key, min, max));
}
/**
* Return the all the elements in the sorted set at key with a score between min and max
* (including elements with score equal to min or max).
*
* The elements having the same score are returned sorted lexicographically as ASCII strings (this
* follows from a property of Redis sorted sets and does not involve further computation).
*
* Using the optional {@link Jedis#zrangeByScore(byte[], double, double, int, int) LIMIT} it is
* possible to get only a range of the matching elements in an SQL-alike way. Note that if offset
* is large the commands needs to traverse the list for offset elements and this adds up to the
* O(M) figure.
*
* The {@link Jedis#zcount(byte[], double, double) ZCOUNT} command is similar to
* {@link Jedis#zrangeByScore(byte[], double, double) ZRANGEBYSCORE} but instead of returning the
* actual elements in the specified interval, it just returns the number of matching elements.
*
* Exclusive intervals and infinity
*
* min and max can be -inf and +inf, so that you are not required to know what's the greatest or
* smallest element in order to take, for instance, elements "up to a given value".
*
* Also while the interval is for default closed (inclusive) it is possible to specify open
* intervals prefixing the score with a "(" character, so for instance:
*
* {@code ZRANGEBYSCORE zset (1.3 5}
*
* Will return all the values with score > 1.3 and <= 5, while for instance:
*
* {@code ZRANGEBYSCORE zset (5 (10}
*
* Will return all the values with score > 5 and < 10 (5 and 10 excluded).
*
* Time complexity:
*
* O(log(N))+O(M) with N being the number of elements in the sorted set and M the number of
* elements returned by the command, so if M is constant (for instance you always ask for the
* first ten elements with LIMIT) you can consider it O(log(N))
* @see Jedis#zrangeByScore(byte[], double, double)
* @see Jedis#zrangeByScore(byte[], double, double, int, int)
* @see Jedis#zrangeByScoreWithScores(byte[], double, double)
* @see Jedis#zrangeByScoreWithScores(byte[], double, double, int, int)
* @see Jedis#zcount(byte[], double, double)
* @param key
* @param min
* @param max
* @param offset
* @param count
* @return A list of elements in the specified score range
*/
@Override
public List zrangeByScore(final byte[] key, final double min, final double max,
final int offset, final int count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrangeByScore(key, min, max, offset, count));
}
@Override
public List zrangeByScore(final byte[] key, final byte[] min, final byte[] max,
final int offset, final int count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrangeByScore(key, min, max, offset, count));
}
/**
* Return the all the elements in the sorted set at key with a score between min and max
* (including elements with score equal to min or max).
*
* The elements having the same score are returned sorted lexicographically as ASCII strings (this
* follows from a property of Redis sorted sets and does not involve further computation).
*
* Using the optional {@link Jedis#zrangeByScore(byte[], double, double, int, int) LIMIT} it is
* possible to get only a range of the matching elements in an SQL-alike way. Note that if offset
* is large the commands needs to traverse the list for offset elements and this adds up to the
* O(M) figure.
*
* The {@link Jedis#zcount(byte[], double, double) ZCOUNT} command is similar to
* {@link Jedis#zrangeByScore(byte[], double, double) ZRANGEBYSCORE} but instead of returning the
* actual elements in the specified interval, it just returns the number of matching elements.
*
* Exclusive intervals and infinity
*
* min and max can be -inf and +inf, so that you are not required to know what's the greatest or
* smallest element in order to take, for instance, elements "up to a given value".
*
* Also while the interval is for default closed (inclusive) it is possible to specify open
* intervals prefixing the score with a "(" character, so for instance:
*
* {@code ZRANGEBYSCORE zset (1.3 5}
*
* Will return all the values with score > 1.3 and <= 5, while for instance:
*
* {@code ZRANGEBYSCORE zset (5 (10}
*
* Will return all the values with score > 5 and < 10 (5 and 10 excluded).
*
* Time complexity:
*
* O(log(N))+O(M) with N being the number of elements in the sorted set and M the number of
* elements returned by the command, so if M is constant (for instance you always ask for the
* first ten elements with LIMIT) you can consider it O(log(N))
* @see Jedis#zrangeByScore(byte[], double, double)
* @see Jedis#zrangeByScore(byte[], double, double, int, int)
* @see Jedis#zrangeByScoreWithScores(byte[], double, double)
* @see Jedis#zrangeByScoreWithScores(byte[], double, double, int, int)
* @see Jedis#zcount(byte[], double, double)
* @param key
* @param min
* @param max
* @return A list of elements in the specified score range
*/
@Override
public List zrangeByScoreWithScores(final byte[] key, final double min, final double max) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrangeByScoreWithScores(key, min, max));
}
@Override
public List zrangeByScoreWithScores(final byte[] key, final byte[] min, final byte[] max) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrangeByScoreWithScores(key, min, max));
}
/**
* Return the all the elements in the sorted set at key with a score between min and max
* (including elements with score equal to min or max).
*
* The elements having the same score are returned sorted lexicographically as ASCII strings (this
* follows from a property of Redis sorted sets and does not involve further computation).
*
* Using the optional {@link Jedis#zrangeByScore(byte[], double, double, int, int) LIMIT} it is
* possible to get only a range of the matching elements in an SQL-alike way. Note that if offset
* is large the commands needs to traverse the list for offset elements and this adds up to the
* O(M) figure.
*
* The {@link Jedis#zcount(byte[], double, double) ZCOUNT} command is similar to
* {@link Jedis#zrangeByScore(byte[], double, double) ZRANGEBYSCORE} but instead of returning the
* actual elements in the specified interval, it just returns the number of matching elements.
*
* Exclusive intervals and infinity
*
* min and max can be -inf and +inf, so that you are not required to know what's the greatest or
* smallest element in order to take, for instance, elements "up to a given value".
*
* Also while the interval is for default closed (inclusive) it is possible to specify open
* intervals prefixing the score with a "(" character, so for instance:
*
* {@code ZRANGEBYSCORE zset (1.3 5}
*
* Will return all the values with score > 1.3 and <= 5, while for instance:
*
* {@code ZRANGEBYSCORE zset (5 (10}
*
* Will return all the values with score > 5 and < 10 (5 and 10 excluded).
*
* Time complexity:
*
* O(log(N))+O(M) with N being the number of elements in the sorted set and M the number of
* elements returned by the command, so if M is constant (for instance you always ask for the
* first ten elements with LIMIT) you can consider it O(log(N))
* @see Jedis#zrangeByScore(byte[], double, double)
* @see Jedis#zrangeByScore(byte[], double, double, int, int)
* @see Jedis#zrangeByScoreWithScores(byte[], double, double)
* @see Jedis#zrangeByScoreWithScores(byte[], double, double, int, int)
* @see Jedis#zcount(byte[], double, double)
* @param key
* @param min
* @param max
* @param offset
* @param count
* @return A list of elements in the specified score range
*/
@Override
public List zrangeByScoreWithScores(final byte[] key, final double min, final double max,
final int offset, final int count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrangeByScoreWithScores(key, min, max, offset, count));
}
@Override
public List zrangeByScoreWithScores(final byte[] key, final byte[] min, final byte[] max,
final int offset, final int count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrangeByScoreWithScores(key, min, max, offset, count));
}
@Override
public List zrevrangeByScore(final byte[] key, final double max, final double min) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrevrangeByScore(key, max, min));
}
@Override
public List zrevrangeByScore(final byte[] key, final byte[] max, final byte[] min) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrevrangeByScore(key, max, min));
}
@Override
public List zrevrangeByScore(final byte[] key, final double max, final double min,
final int offset, final int count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrevrangeByScore(key, max, min, offset, count));
}
@Override
public List zrevrangeByScore(final byte[] key, final byte[] max, final byte[] min,
final int offset, final int count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrevrangeByScore(key, max, min, offset, count));
}
@Override
public List zrevrangeByScoreWithScores(final byte[] key, final double max, final double min) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min));
}
@Override
public List zrevrangeByScoreWithScores(final byte[] key, final double max,
final double min, final int offset, final int count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min, offset, count));
}
@Override
public List zrevrangeByScoreWithScores(final byte[] key, final byte[] max, final byte[] min) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min));
}
@Override
public List zrevrangeByScoreWithScores(final byte[] key, final byte[] max,
final byte[] min, final int offset, final int count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrevrangeByScoreWithScores(key, max, min, offset, count));
}
/**
* Remove all elements in the sorted set at key with rank between start and end. Start and end are
* 0-based with rank 0 being the element with the lowest score. Both start and end can be negative
* numbers, where they indicate offsets starting at the element with the highest rank. For
* example: -1 is the element with the highest score, -2 the element with the second highest score
* and so forth.
*
* Time complexity: O(log(N))+O(M) with N being the number of elements in the sorted set
* and M the number of elements removed by the operation
* @param key
* @param start
* @param stop
* @return The number of elements removed
*/
@Override
public long zremrangeByRank(final byte[] key, final long start, final long stop) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zremrangeByRank(key, start, stop));
}
/**
* Remove all the elements in the sorted set at key with a score between min and max (including
* elements with score equal to min or max).
*
* Time complexity:
*
* O(log(N))+O(M) with N being the number of elements in the sorted set and M the number of
* elements removed by the operation
* @param key
* @param min
* @param max
* @return The number of elements removed
*/
@Override
public long zremrangeByScore(final byte[] key, final double min, final double max) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zremrangeByScore(key, min, max));
}
@Override
public long zremrangeByScore(final byte[] key, final byte[] min, final byte[] max) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zremrangeByScore(key, min, max));
}
/**
* Add multiple sorted sets, This command is similar to ZUNIONSTORE, but instead of storing the
* resulting sorted set, it is returned to the connection.
* @param params
* @param keys
* @return The result of the union
*/
@Override
public List zunion(final ZParams params, final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zunion(params, keys));
}
/**
* Add multiple sorted sets with scores, This command is similar to ZUNIONSTORE, but instead of
* storing the resulting sorted set, it is returned to the connection.
* @param params
* @param keys
* @return The result of the union with their scores
*/
@Override
public List zunionWithScores(final ZParams params, final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zunionWithScores(params, keys));
}
/**
* Creates a union or intersection of N sorted sets given by keys k1 through kN, and stores it at
* dstkey. It is mandatory to provide the number of input keys N, before passing the input keys
* and the other (optional) arguments.
*
* As the terms imply, the {@link Jedis#zinterstore(byte[], byte[][])} ZINTERSTORE} command
* requires an element to be present in each of the given inputs to be inserted in the result. The
* {@link Jedis#zunionstore(byte[], byte[][])} command inserts all elements across all inputs.
*
* Using the WEIGHTS option, it is possible to add weight to each input sorted set. This means
* that the score of each element in the sorted set is first multiplied by this weight before
* being passed to the aggregation. When this option is not given, all weights default to 1.
*
* With the AGGREGATE option, it is possible to specify how the results of the union or
* intersection are aggregated. This option defaults to SUM, where the score of an element is
* summed across the inputs where it exists. When this option is set to be either MIN or MAX, the
* resulting set will contain the minimum or maximum score of an element across the inputs where
* it exists.
*
* Time complexity: O(N) + O(M log(M)) with N being the sum of the sizes of the input
* sorted sets, and M being the number of elements in the resulting sorted set
* @param dstkey
* @param sets
* @return The number of elements in the sorted set at dstkey
*/
@Override
public long zunionstore(final byte[] dstkey, final byte[]... sets) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zunionstore(dstkey, sets));
}
/**
* Creates a union or intersection of N sorted sets given by keys k1 through kN, and stores it at
* dstkey. It is mandatory to provide the number of input keys N, before passing the input keys
* and the other (optional) arguments.
*
* As the terms imply, the {@link Jedis#zinterstore(byte[], byte[][]) ZINTERSTORE} command
* requires an element to be present in each of the given inputs to be inserted in the result. The
* {@link Jedis#zunionstore(byte[], byte[][]) ZUNIONSTORE} command inserts all elements across
* all inputs.
*
* Using the WEIGHTS option, it is possible to add weight to each input sorted set. This means
* that the score of each element in the sorted set is first multiplied by this weight before
* being passed to the aggregation. When this option is not given, all weights default to 1.
*
* With the AGGREGATE option, it is possible to specify how the results of the union or
* intersection are aggregated. This option defaults to SUM, where the score of an element is
* summed across the inputs where it exists. When this option is set to be either MIN or MAX, the
* resulting set will contain the minimum or maximum score of an element across the inputs where
* it exists.
*
* Time complexity: O(N) + O(M log(M)) with N being the sum of the sizes of the input
* sorted sets, and M being the number of elements in the resulting sorted set
* @param dstkey
* @param sets
* @param params
* @return The number of elements in the sorted set at dstkey
*/
@Override
public long zunionstore(final byte[] dstkey, final ZParams params, final byte[]... sets) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zunionstore(dstkey, params, sets));
}
/**
* Intersect multiple sorted sets, This command is similar to ZINTERSTORE, but instead of storing
* the resulting sorted set, it is returned to the connection.
* @param params
* @param keys
* @return The result of the intersection
*/
@Override
public List zinter(final ZParams params, final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zinter(params, keys));
}
/**
* Intersect multiple sorted sets, This command is similar to ZINTERSTORE, but instead of storing
* the resulting sorted set, it is returned to the connection.
* @param params
* @param keys
* @return The result of the intersection with scores
*/
@Override
public List zinterWithScores(final ZParams params, final byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zinterWithScores(params, keys));
}
/**
* Creates a union or intersection of N sorted sets given by keys k1 through kN, and stores it at
* dstkey. It is mandatory to provide the number of input keys N, before passing the input keys
* and the other (optional) arguments.
*
* As the terms imply, the {@link Jedis#zinterstore(byte[], byte[][]) ZINTERSTORE} command
* requires an element to be present in each of the given inputs to be inserted in the result. The
* {@link Jedis#zunionstore(byte[], byte[][]) ZUNIONSTORE} command inserts all elements across all
* inputs.
*
* Using the WEIGHTS option, it is possible to add weight to each input sorted set. This means
* that the score of each element in the sorted set is first multiplied by this weight before
* being passed to the aggregation. When this option is not given, all weights default to 1.
*
* With the AGGREGATE option, it is possible to specify how the results of the union or
* intersection are aggregated. This option defaults to SUM, where the score of an element is
* summed across the inputs where it exists. When this option is set to be either MIN or MAX, the
* resulting set will contain the minimum or maximum score of an element across the inputs where
* it exists.
*
* Time complexity: O(N) + O(M log(M)) with N being the sum of the sizes of the input
* sorted sets, and M being the number of elements in the resulting sorted set
* @param dstkey
* @param sets
* @return The number of elements in the sorted set at dstkey
*/
@Override
public long zinterstore(final byte[] dstkey, final byte[]... sets) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zinterstore(dstkey, sets));
}
/**
* Creates a union or intersection of N sorted sets given by keys k1 through kN, and stores it at
* dstkey. It is mandatory to provide the number of input keys N, before passing the input keys
* and the other (optional) arguments.
*
* As the terms imply, the {@link Jedis#zinterstore(byte[], byte[][]) ZINTERSTORE} command
* requires an element to be present in each of the given inputs to be inserted in the result. The
* {@link Jedis#zunionstore(byte[], byte[][]) ZUNIONSTORE} command inserts all elements across all
* inputs.
*
* Using the WEIGHTS option, it is possible to add weight to each input sorted set. This means
* that the score of each element in the sorted set is first multiplied by this weight before
* being passed to the aggregation. When this option is not given, all weights default to 1.
*
* With the AGGREGATE option, it is possible to specify how the results of the union or
* intersection are aggregated. This option defaults to SUM, where the score of an element is
* summed across the inputs where it exists. When this option is set to be either MIN or MAX, the
* resulting set will contain the minimum or maximum score of an element across the inputs where
* it exists.
*
* Time complexity: O(N) + O(M log(M)) with N being the sum of the sizes of the input
* sorted sets, and M being the number of elements in the resulting sorted set
* @param dstkey
* @param sets
* @param params
* @return The number of elements in the sorted set at dstkey
*/
@Override
public long zinterstore(final byte[] dstkey, final ZParams params, final byte[]... sets) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zinterstore(dstkey, params, sets));
}
@Override
public long zintercard(byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zintercard(keys));
}
@Override
public long zintercard(long limit, byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zintercard(limit, keys));
}
@Override
public long zlexcount(final byte[] key, final byte[] min, final byte[] max) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zlexcount(key, min, max));
}
@Override
public List zrangeByLex(final byte[] key, final byte[] min, final byte[] max) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrangeByLex(key, min, max));
}
@Override
public List zrangeByLex(final byte[] key, final byte[] min, final byte[] max,
final int offset, final int count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrangeByLex(key, min, max, offset, count));
}
@Override
public List zrevrangeByLex(final byte[] key, final byte[] max, final byte[] min) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrevrangeByLex(key, max, min));
}
@Override
public List zrevrangeByLex(final byte[] key, final byte[] max, final byte[] min,
final int offset, final int count) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zrevrangeByLex(key, max, min, offset, count));
}
@Override
public long zremrangeByLex(final byte[] key, final byte[] min, final byte[] max) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zremrangeByLex(key, min, max));
}
@Override
public KeyValue> zmpop(SortedSetOption option, byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zmpop(option, keys));
}
@Override
public KeyValue> zmpop(SortedSetOption option, int count, byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.zmpop(option, count, keys));
}
@Override
public KeyValue> bzmpop(double timeout, SortedSetOption option, byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.bzmpop(timeout, option, keys));
}
@Override
public KeyValue> bzmpop(double timeout, SortedSetOption option, int count, byte[]... keys) {
checkIsInMultiOrPipeline();
return connection.executeCommand(commandObjects.bzmpop(timeout, option, count, keys));
}
/**
* Synchronously save the DB on disk.
*
* Save the whole dataset on disk (this means that all the databases are saved, as well as keys
* with an EXPIRE set (the expire is preserved). The server hangs while the saving is not
* completed, no connection is served in the meanwhile. An OK code is returned when the DB was
* fully stored in disk.
*
* The background variant of this command is {@link Jedis#bgsave() BGSAVE} that is able to perform
* the saving in the background while the server continues serving other clients.
*
* @return OK
*/
@Override
public String save() {
connection.sendCommand(Command.SAVE);
return connection.getStatusCodeReply();
}
/**
* Asynchronously save the DB on disk.
*
* Save the DB in background. The OK code is immediately returned. Redis forks, the parent
* continues to server the clients, the child saves the DB on disk then exit. A connection my be able
* to check if the operation succeeded using the LASTSAVE command.
* @return OK
*/
@Override
public String bgsave() {
connection.sendCommand(BGSAVE);
return connection.getStatusCodeReply();
}
@Override
public String bgsaveSchedule() {
connection.sendCommand(BGSAVE, SCHEDULE);
return connection.getStatusCodeReply();
}
/**
* Rewrite the append only file in background when it gets too big. Please for detailed
* information about the Redis Append Only File check the Append Only File Howto.
*
* BGREWRITEAOF rewrites the Append Only File in background when it gets too big. The Redis Append
* Only File is a Journal, so every operation modifying the dataset is logged in the Append Only
* File (and replayed at startup). This means that the Append Only File always grows. In order to
* rebuild its content the BGREWRITEAOF creates a new version of the append only file starting
* directly form the dataset in memory in order to guarantee the generation of the minimal number
* of commands needed to rebuild the database.
*
* @return OK
*/
@Override
public String bgrewriteaof() {
connection.sendCommand(BGREWRITEAOF);
return connection.getStatusCodeReply();
}
/**
* Return the UNIX time stamp of the last successfully saving of the dataset on disk.
*
* Return the UNIX TIME of the last DB save executed with success. A connection may check if a
* {@link Jedis#bgsave() BGSAVE} command succeeded reading the LASTSAVE value, then issuing a
* BGSAVE command and checking at regular intervals every N seconds if LASTSAVE changed.
* @return An UNIX time stamp
*/
@Override
public long lastsave() {
connection.sendCommand(LASTSAVE);
return connection.getIntegerReply();
}
/**
* Synchronously save the DB on disk, then shutdown the server.
*
* Stop all the clients, save the DB, then quit the server. This commands makes sure that the DB
* is switched off without the lost of any data.
* @throws JedisException with the status code reply on error. On success nothing is thrown since
* the server quits and the connection is closed.
*/
@Override
public void shutdown() throws JedisException {
connection.sendCommand(SHUTDOWN);
try {
throw new JedisException(connection.getStatusCodeReply());
} catch (JedisConnectionException jce) {
// expected
connection.setBroken();
}
}
@Override
public void shutdown(ShutdownParams shutdownParams) throws JedisException {
connection.sendCommand(new CommandArguments(SHUTDOWN).addParams(shutdownParams));
try {
throw new JedisException(connection.getStatusCodeReply());
} catch (JedisConnectionException jce) {
// expected
connection.setBroken();
}
}
@Override
public String shutdownAbort() {
connection.sendCommand(SHUTDOWN, ABORT);
return connection.getStatusCodeReply();
}
/**
* Provide information and statistics about the server.
*
* The info command returns different information and statistics about the server in an format
* that's simple to parse by computers and easy to read by humans.
*
* Format of the returned String:
*
* All the fields are in the form field:value
*
*
* edis_version:0.07
* connected_clients:1
* connected_slaves:0
* used_memory:3187
* changes_since_last_save:0
* last_save_time:1237655729
* total_connections_received:1
* total_commands_processed:1
* uptime_in_seconds:25
* uptime_in_days:0
*
*
* Notes
*
* used_memory is returned in bytes, and is the total number of bytes allocated by the program
* using malloc.
*
* uptime_in_days is redundant since the uptime in seconds contains already the full uptime
* information, this field is only mainly present for humans.
*
* changes_since_last_save does not refer to the number of key changes, but to the number of
* operations that produced some kind of change in the dataset.
*
* @return Bulk reply
*/
@Override
public String info() {
connection.sendCommand(Command.INFO);
return connection.getBulkReply();
}
@Override
public String info(final String section) {
connection.sendCommand(Command.INFO, section);
return connection.getBulkReply();
}
/**
* Dump all the received requests in real time.
*
* MONITOR is a debugging command that outputs the whole sequence of commands received by the
* Redis server. is very handy in order to understand what is happening into the database. This
* command is used directly via telnet.
* @param jedisMonitor
*/
public void monitor(final JedisMonitor jedisMonitor) {
// connection.monitor();
connection.sendCommand(Command.MONITOR);
connection.getStatusCodeReply();
jedisMonitor.proceed(connection);
}
/**
* Change the replication settings.
*
* The SLAVEOF command can change the replication settings of a slave on the fly. If a Redis
* server is already acting as slave, the command SLAVEOF NO ONE will turn off the replication
* turning the Redis server into a MASTER. In the proper form SLAVEOF hostname port will make the
* server a slave of the specific server listening at the specified hostname and port.
*
* If a server is already a slave of some master, SLAVEOF hostname port will stop the replication
* against the old server and start the synchronization against the new one discarding the old
* dataset.
*
* The form SLAVEOF no one will stop replication turning the server into a MASTER but will not
* discard the replication. So if the old master stop working it is possible to turn the slave
* into a master and set the application to use the new master in read/write. Later when the other
* Redis server will be fixed it can be configured in order to work as slave.
* @param host
* @param port
* @return OK
* @deprecated Use {@link Jedis#replicaof(java.lang.String, int)}.
*/
@Override
@Deprecated
public String slaveof(final String host, final int port) {
connection.sendCommand(SLAVEOF, encode(host), toByteArray(port));
return connection.getStatusCodeReply();
}
/**
* @deprecated Use {@link Jedis#replicaofNoOne()}.
*/
@Override
@Deprecated
public String slaveofNoOne() {
connection.sendCommand(SLAVEOF, NO.getRaw(), ONE.getRaw());
return connection.getStatusCodeReply();
}
@Override
public String replicaof(final String host, final int port) {
connection.sendCommand(REPLICAOF, encode(host), toByteArray(port));
return connection.getStatusCodeReply();
}
@Override
public String replicaofNoOne() {
connection.sendCommand(REPLICAOF, NO.getRaw(), ONE.getRaw());
return connection.getStatusCodeReply();
}
@Override
public List