
redis.clients.jedis.BinaryJedis Maven / Gradle / Ivy
Show all versions of jedis Show documentation
/**
* The following only applies to changes made to this file as part of YugaByte development.
*
* Portions Copyright (c) YugaByte, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
package redis.clients.jedis;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.jedis.exceptions.InvalidURIException;
import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.exceptions.JedisException;
import redis.clients.jedis.params.geo.GeoRadiusParam;
import redis.clients.jedis.params.sortedset.ZAddParams;
import redis.clients.jedis.params.sortedset.ZIncrByParams;
import redis.clients.util.JedisByteHashMap;
import redis.clients.util.JedisURIHelper;
import redis.clients.util.SafeEncoder;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocketFactory;
import java.io.Closeable;
import java.io.Serializable;
import java.net.URI;
import java.util.*;
import static redis.clients.jedis.Protocol.toByteArray;
public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKeyBinaryCommands,
AdvancedBinaryJedisCommands, BinaryScriptingCommands, Closeable {
protected Client client = null;
protected Transaction transaction = null;
protected Pipeline pipeline = null;
public BinaryJedis() {
client = new Client();
}
public BinaryJedis(final String host) {
URI uri = URI.create(host);
if (uri.getScheme() != null && uri.getScheme().equals("redis")) {
initializeClientFromURI(uri);
} else {
client = new Client(host);
}
}
public BinaryJedis(final String host, final int port) {
client = new Client(host, port);
}
public BinaryJedis(final String host, final int port, final boolean ssl) {
client = new Client(host, port, ssl);
}
public BinaryJedis(final String host, final int port, final boolean ssl,
final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters,
final HostnameVerifier hostnameVerifier) {
client = new Client(host, port, ssl, sslSocketFactory, sslParameters, hostnameVerifier);
}
public BinaryJedis(final String host, final int port, final int timeout) {
client = new Client(host, port);
client.setConnectionTimeout(timeout);
client.setSoTimeout(timeout);
}
public BinaryJedis(final String host, final int port, final int timeout, final boolean ssl) {
client = new Client(host, port, ssl);
client.setConnectionTimeout(timeout);
client.setSoTimeout(timeout);
}
public BinaryJedis(final String host, final int port, final int timeout, final boolean ssl,
final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters,
final HostnameVerifier hostnameVerifier) {
client = new Client(host, port, ssl, sslSocketFactory, sslParameters, hostnameVerifier);
client.setConnectionTimeout(timeout);
client.setSoTimeout(timeout);
}
public BinaryJedis(final String host, final int port, final int connectionTimeout,
final int soTimeout) {
client = new Client(host, port);
client.setConnectionTimeout(connectionTimeout);
client.setSoTimeout(soTimeout);
}
public BinaryJedis(final String host, final int port, final int connectionTimeout,
final int soTimeout, final boolean ssl) {
client = new Client(host, port, ssl);
client.setConnectionTimeout(connectionTimeout);
client.setSoTimeout(soTimeout);
}
public BinaryJedis(final String host, final int port, final int connectionTimeout,
final int soTimeout, final boolean ssl, final SSLSocketFactory sslSocketFactory,
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
client = new Client(host, port, ssl, sslSocketFactory, sslParameters, hostnameVerifier);
client.setConnectionTimeout(connectionTimeout);
client.setSoTimeout(soTimeout);
}
public BinaryJedis(final JedisShardInfo shardInfo) {
client = new Client(shardInfo.getHost(), shardInfo.getPort(), shardInfo.getSsl(),
shardInfo.getSslSocketFactory(), shardInfo.getSslParameters(),
shardInfo.getHostnameVerifier());
client.setConnectionTimeout(shardInfo.getConnectionTimeout());
client.setSoTimeout(shardInfo.getSoTimeout());
client.setPassword(shardInfo.getPassword());
client.setDb(shardInfo.getDb());
}
public BinaryJedis(URI uri) {
initializeClientFromURI(uri);
}
public BinaryJedis(URI uri, final SSLSocketFactory sslSocketFactory,
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
initializeClientFromURI(uri, sslSocketFactory, sslParameters, hostnameVerifier);
}
public BinaryJedis(final URI uri, final int timeout) {
initializeClientFromURI(uri);
client.setConnectionTimeout(timeout);
client.setSoTimeout(timeout);
}
public BinaryJedis(final URI uri, final int timeout, final SSLSocketFactory sslSocketFactory,
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
initializeClientFromURI(uri, sslSocketFactory, sslParameters, hostnameVerifier);
client.setConnectionTimeout(timeout);
client.setSoTimeout(timeout);
}
public BinaryJedis(final URI uri, final int connectionTimeout, final int soTimeout) {
initializeClientFromURI(uri);
client.setConnectionTimeout(connectionTimeout);
client.setSoTimeout(soTimeout);
}
public BinaryJedis(final URI uri, final int connectionTimeout, final int soTimeout,
final SSLSocketFactory sslSocketFactory,final SSLParameters sslParameters,
final HostnameVerifier hostnameVerifier) {
initializeClientFromURI(uri, sslSocketFactory, sslParameters, hostnameVerifier);
client.setConnectionTimeout(connectionTimeout);
client.setSoTimeout(soTimeout);
}
private void initializeClientFromURI(URI uri) {
if (!JedisURIHelper.isValid(uri)) {
throw new InvalidURIException(String.format(
"Cannot open Redis connection due invalid URI. %s", uri.toString()));
}
client = new Client(uri.getHost(), uri.getPort(), uri.getScheme().equals("rediss"));
String password = JedisURIHelper.getPassword(uri);
if (password != null) {
client.auth(password);
client.getStatusCodeReply();
}
int dbIndex = JedisURIHelper.getDBIndex(uri);
if (dbIndex > 0) {
client.select(dbIndex);
client.getStatusCodeReply();
client.setDb(dbIndex);
}
}
private void initializeClientFromURI(URI uri, final SSLSocketFactory sslSocketFactory,
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
if (!JedisURIHelper.isValid(uri)) {
throw new InvalidURIException(String.format(
"Cannot open Redis connection due invalid URI. %s", uri.toString()));
}
client = new Client(uri.getHost(), uri.getPort(), uri.getScheme().equals("rediss"),
sslSocketFactory, sslParameters, hostnameVerifier);
String password = JedisURIHelper.getPassword(uri);
if (password != null) {
client.auth(password);
client.getStatusCodeReply();
}
int dbIndex = JedisURIHelper.getDBIndex(uri);
if (dbIndex > 0) {
client.select(dbIndex);
client.getStatusCodeReply();
client.setDb(dbIndex);
}
}
@Override
public String ping() {
checkIsInMultiOrPipeline();
client.ping();
return client.getStatusCodeReply();
}
/**
* 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 Status code reply
*/
public String set(final byte[] key, final byte[] value) {
checkIsInMultiOrPipeline();
client.set(key, value);
return client.getStatusCodeReply();
}
/**
* 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 nxxx NX|XX, NX -- Only set the key if it does not already exist. XX -- Only set the key
* if it already exist.
* @param expx EX|PX, expire time units: EX = seconds; PX = milliseconds
* @param time expire time in the units of expx
* @return Status code reply
*/
public String set(final byte[] key, final byte[] value, final byte[] nxxx, final byte[] expx,
final long time) {
checkIsInMultiOrPipeline();
client.set(key, value, nxxx, expx, time);
return client.getStatusCodeReply();
}
/**
* 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
*/
public byte[] get(final byte[] key) {
checkIsInMultiOrPipeline();
client.get(key);
return client.getBinaryBulkReply();
}
/**
* Ask the server to silently close the connection.
*/
public String quit() {
checkIsInMultiOrPipeline();
client.quit();
return client.getStatusCodeReply();
}
/**
* Test if the specified keys exist. The command returns the number of keys existed Time
* complexity: O(N)
* @param keys
* @return Integer reply, specifically: an integer greater than 0 if one or more keys existed 0 if
* none of the specified keys existed
*/
public Long exists(final byte[]... keys) {
checkIsInMultiOrPipeline();
client.exists(keys);
return client.getIntegerReply();
}
/**
* Test if the specified key exists. The command returns "1" if the key exists, otherwise "0" is
* returned. Note that even keys set with an empty string as value will return "1". Time
* complexity: O(1)
* @param key
* @return Boolean reply, true if the key exists, otherwise false
*/
public Boolean exists(final byte[] key) {
checkIsInMultiOrPipeline();
client.exists(key);
return client.getIntegerReply() == 1;
}
/**
* 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 Integer reply, specifically: an integer greater than 0 if one or more keys were removed
* 0 if none of the specified key existed
*/
public Long del(final byte[]... keys) {
checkIsInMultiOrPipeline();
client.del(keys);
return client.getIntegerReply();
}
public Long del(final byte[] key) {
checkIsInMultiOrPipeline();
client.del(key);
return client.getIntegerReply();
}
/**
* 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 Status code reply, specifically: "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
*/
public String type(final byte[] key) {
checkIsInMultiOrPipeline();
client.type(key);
return client.getStatusCodeReply();
}
/**
* Delete all the keys of the currently selected DB. This command never fails.
* @return Status code reply
*/
public String flushDB() {
checkIsInMultiOrPipeline();
client.flushDB();
return client.getStatusCodeReply();
}
/**
* 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
*/
public Set keys(final byte[] pattern) {
checkIsInMultiOrPipeline();
client.keys(pattern);
return SetFromList.of(client.getBinaryMultiBulkReply());
}
/**
* Return a randomly selected key from the currently selected DB.
*
* Time complexity: O(1)
* @return Singe line reply, specifically the randomly selected key or an empty string is the
* database is empty
*/
public byte[] randomBinaryKey() {
checkIsInMultiOrPipeline();
client.randomKey();
return client.getBinaryBulkReply();
}
/**
* 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 Status code repy
*/
public String rename(final byte[] oldkey, final byte[] newkey) {
checkIsInMultiOrPipeline();
client.rename(oldkey, newkey);
return client.getStatusCodeReply();
}
/**
* Rename oldkey into newkey but fails if the destination key newkey already exists.
*
* Time complexity: O(1)
* @param oldkey
* @param newkey
* @return Integer reply, specifically: 1 if the key was renamed 0 if the target key already exist
*/
public Long renamenx(final byte[] oldkey, final byte[] newkey) {
checkIsInMultiOrPipeline();
client.renamenx(oldkey, newkey);
return client.getIntegerReply();
}
/**
* Return the number of keys in the currently selected database.
* @return Integer reply
*/
public Long dbSize() {
checkIsInMultiOrPipeline();
client.dbSize();
return client.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.
*
* Voltile 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 #persist(byte[]) PERSIST} command.
*
* Time complexity: O(1)
* @see ExpireCommand
* @param key
* @param seconds
* @return Integer reply, specifically: 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.
*/
public Long expire(final byte[] key, final int seconds) {
checkIsInMultiOrPipeline();
client.expire(key, seconds);
return client.getIntegerReply();
}
/**
* @deprecated use BinaryJedis.pexpire(byte[], long) or Jedis.pexpire(String,long) 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.
*
* Voltile 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 #persist(byte[]) PERSIST} command.
*
* Time complexity: O(1)
* @see PEXPIRE Command
* @param key
* @param milliseconds
* @return Integer reply, specifically: 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.
*/
@Deprecated
public Long pexpire(String key, final long milliseconds) {
checkIsInMultiOrPipeline();
client.pexpire(key, milliseconds);
return client.getIntegerReply();
}
/**
* EXPIREAT works exctly like {@link #expire(byte[], int) 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 specifing 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 #persist(byte[]) PERSIST} command.
*
* Time complexity: O(1)
* @see ExpireCommand
* @param key
* @param unixTime
* @return Integer reply, specifically: 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.
*/
public Long expireAt(final byte[] key, final long unixTime) {
checkIsInMultiOrPipeline();
client.expireAt(key, unixTime);
return client.getIntegerReply();
}
/**
* The TTL command returns the remaining time to live in seconds of a key that has an
* {@link #expire(byte[], int) EXPIRE} set. This introspection capability allows a Redis client to
* check how many seconds a given key will continue to be part of the dataset.
* @param key
* @return Integer reply, returns the remaining time to live in seconds of a key that has an
* EXPIRE. If the Key does not exists or does not have an associated expire, -1 is
* returned.
*/
public Long ttl(final byte[] key) {
checkIsInMultiOrPipeline();
client.ttl(key);
return client.getIntegerReply();
}
/**
* Select the DB with having the specified zero-based numeric index. For default every new client
* connection is automatically selected to DB 0.
* @param index
* @return Status code reply
*/
public String select(final int index) {
checkIsInMultiOrPipeline();
client.select(index);
String statusCodeReply = client.getStatusCodeReply();
client.setDb(index);
return statusCodeReply;
}
/**
* 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 Integer reply, specifically: 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.
*/
public Long move(final byte[] key, final int dbIndex) {
checkIsInMultiOrPipeline();
client.move(key, dbIndex);
return client.getIntegerReply();
}
/**
* Delete all the keys of all the existing databases, not just the currently selected one. This
* command never fails.
* @return Status code reply
*/
public String flushAll() {
checkIsInMultiOrPipeline();
client.flushAll();
return client.getStatusCodeReply();
}
/**
* 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
*/
public byte[] getSet(final byte[] key, final byte[] value) {
checkIsInMultiOrPipeline();
client.getSet(key, value);
return client.getBinaryBulkReply();
}
/**
* Get the values of all the specified keys. If one or more keys dont 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
*/
public List mget(final byte[]... keys) {
checkIsInMultiOrPipeline();
client.mget(keys);
return client.getBinaryMultiBulkReply();
}
/**
* SETNX works exactly like {@link #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 Integer reply, specifically: 1 if the key was set 0 if the key was not set
*/
public Long setnx(final byte[] key, final byte[] value) {
checkIsInMultiOrPipeline();
client.setnx(key, value);
return client.getIntegerReply();
}
/**
* The command is exactly equivalent to the following group of commands:
* {@link #set(byte[], byte[]) SET} + {@link #expire(byte[], int) EXPIRE}. The operation is
* atomic.
*
* Time complexity: O(1)
* @param key
* @param seconds
* @param value
* @return Status code reply
*/
public String setex(final byte[] key, final int seconds, final byte[] value) {
checkIsInMultiOrPipeline();
client.setex(key, seconds, value);
return client.getStatusCodeReply();
}
/**
* Set the the respective keys to the respective values. MSET will replace old values with new
* values, while {@link #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 client talking to Redis can either see the changes to both A and B at
* once, or no modification at all.
* @see #msetnx(byte[]...)
* @param keysvalues
* @return Status code reply Basically +OK as MSET can't fail
*/
public String mset(final byte[]... keysvalues) {
checkIsInMultiOrPipeline();
client.mset(keysvalues);
return client.getStatusCodeReply();
}
/**
* Set the the respective keys to the respective values. {@link #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 client talking to Redis can either see the changes to both A and B at
* once, or no modification at all.
* @see #mset(byte[]...)
* @param keysvalues
* @return Integer reply, specifically: 1 if the all the keys were set 0 if no key was set (at
* least one key already existed)
*/
public Long msetnx(final byte[]... keysvalues) {
checkIsInMultiOrPipeline();
client.msetnx(keysvalues);
return client.getIntegerReply();
}
/**
* DECRBY work just like {@link #decr(byte[]) INCR} but instead to decrement by 1 the decrement 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 #incr(byte[])
* @see #decr(byte[])
* @see #incrBy(byte[], long)
* @param key
* @param integer
* @return Integer reply, this commands will reply with the new value of key after the increment.
*/
public Long decrBy(final byte[] key, final long integer) {
checkIsInMultiOrPipeline();
client.decrBy(key, integer);
return client.getIntegerReply();
}
/**
* 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.
*
* 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 #incr(byte[])
* @see #incrBy(byte[], long)
* @see #decrBy(byte[], long)
* @param key
* @return Integer reply, this commands will reply with the new value of key after the increment.
*/
public Long decr(final byte[] key) {
checkIsInMultiOrPipeline();
client.decr(key);
return client.getIntegerReply();
}
/**
* INCRBY work just like {@link #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 #incr(byte[])
* @see #decr(byte[])
* @see #decrBy(byte[], long)
* @param key
* @param integer
* @return Integer reply, this commands will reply with the new value of key after the increment.
*/
public Long incrBy(final byte[] key, final long integer) {
checkIsInMultiOrPipeline();
client.incrBy(key, integer);
return client.getIntegerReply();
}
/**
* INCRBYFLOAT work just like {@link #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 #incr(byte[])
* @see #decr(byte[])
* @see #decrBy(byte[], long)
* @param key the key to increment
* @param integer the value to increment by
* @return Integer reply, this commands will reply with the new value of key after the increment.
*/
public Double incrByFloat(final byte[] key, final double integer) {
checkIsInMultiOrPipeline();
client.incrByFloat(key, integer);
String dval = client.getBulkReply();
return (dval != null ? new Double(dval) : null);
}
/**
* 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 #incrBy(byte[], long)
* @see #decr(byte[])
* @see #decrBy(byte[], long)
* @param key
* @return Integer reply, this commands will reply with the new value of key after the increment.
*/
public Long incr(final byte[] key) {
checkIsInMultiOrPipeline();
client.incr(key);
return client.getIntegerReply();
}
/**
* 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 Integer reply, specifically the total length of the string after the append operation.
*/
public Long append(final byte[] key, final byte[] value) {
checkIsInMultiOrPipeline();
client.append(key, value);
return client.getIntegerReply();
}
/**
* 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
*/
public byte[] substr(final byte[] key, final int start, final int end) {
checkIsInMultiOrPipeline();
client.substr(key, start, end);
return client.getBinaryBulkReply();
}
/**
* 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.
*/
public Long hset(final byte[] key, final byte[] field, final byte[] value) {
checkIsInMultiOrPipeline();
client.hset(key, field, value);
return client.getIntegerReply();
}
/**
* 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
*/
public byte[] hget(final byte[] key, final byte[] field) {
checkIsInMultiOrPipeline();
client.hget(key, field);
return client.getBinaryBulkReply();
}
/**
* 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.
*/
public Long hsetnx(final byte[] key, final byte[] field, final byte[] value) {
checkIsInMultiOrPipeline();
client.hsetnx(key, field, value);
return client.getIntegerReply();
}
/**
* 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 Always OK because HMSET can't fail
*/
public String hmset(final byte[] key, final Map hash) {
checkIsInMultiOrPipeline();
client.hmset(key, hash);
return client.getStatusCodeReply();
}
/**
* 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 Multi Bulk Reply specifically a list of all the values associated with the specified
* fields, in the same order of the request.
*/
public List hmget(final byte[] key, final byte[]... fields) {
checkIsInMultiOrPipeline();
client.hmget(key, fields);
return client.getBinaryMultiBulkReply();
}
/**
* 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 Integer reply The new value at field after the increment operation.
*/
public Long hincrBy(final byte[] key, final byte[] field, final long value) {
checkIsInMultiOrPipeline();
client.hincrBy(key, field, value);
return client.getIntegerReply();
}
/**
* 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 Double precision floating point reply The new value at field after the increment
* operation.
*/
public Double hincrByFloat(final byte[] key, final byte[] field, final double value) {
checkIsInMultiOrPipeline();
client.hincrByFloat(key, field, value);
final String dval = client.getBulkReply();
return (dval != null ? new Double(dval) : null);
}
/**
* Test for existence of a specified field in a hash. Time complexity: O(1)
* @param key
* @param field
* @return Return 1 if the hash stored at key contains the specified field. Return 0 if the key is
* not found or the field is not present.
*/
public Boolean hexists(final byte[] key, final byte[] field) {
checkIsInMultiOrPipeline();
client.hexists(key, field);
return client.getIntegerReply() == 1;
}
/**
* 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.
*/
public Long hdel(final byte[] key, final byte[]... fields) {
checkIsInMultiOrPipeline();
client.hdel(key, fields);
return client.getIntegerReply();
}
/**
* 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.
*/
public Long hlen(final byte[] key) {
checkIsInMultiOrPipeline();
client.hlen(key);
return client.getIntegerReply();
}
/**
* 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.
*/
public Set hkeys(final byte[] key) {
checkIsInMultiOrPipeline();
client.hkeys(key);
return SetFromList.of(client.getBinaryMultiBulkReply());
}
/**
* 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.
*/
public List hvals(final byte[] key) {
checkIsInMultiOrPipeline();
client.hvals(key);
return client.getBinaryMultiBulkReply();
}
/**
* 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.
*/
public Map hgetAll(final byte[] key) {
checkIsInMultiOrPipeline();
client.hgetAll(key);
final List flatHash = client.getBinaryMultiBulkReply();
final Map hash = new JedisByteHashMap();
final Iterator iterator = flatHash.iterator();
while (iterator.hasNext()) {
hash.put(iterator.next(), iterator.next());
}
return hash;
}
/**
* 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)
* @see BinaryJedis#rpush(byte[], byte[]...)
* @param key
* @param strings
* @return Integer reply, specifically, the number of elements inside the list after the push
* operation.
*/
public Long rpush(final byte[] key, final byte[]... strings) {
checkIsInMultiOrPipeline();
client.rpush(key, strings);
return client.getIntegerReply();
}
/**
* 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)
* @see BinaryJedis#rpush(byte[], byte[]...)
* @param key
* @param strings
* @return Integer reply, specifically, the number of elements inside the list after the push
* operation.
*/
public Long lpush(final byte[] key, final byte[]... strings) {
checkIsInMultiOrPipeline();
client.lpush(key, strings);
return client.getIntegerReply();
}
/**
* 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.
*/
public Long llen(final byte[] key) {
checkIsInMultiOrPipeline();
client.llen(key);
return client.getIntegerReply();
}
/**
* 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 end
* @return Multi bulk reply, specifically a list of elements in the specified range.
*/
public List lrange(final byte[] key, final long start, final long end) {
checkIsInMultiOrPipeline();
client.lrange(key, start, end);
return client.getBinaryMultiBulkReply();
}
/**
* 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 end
* @return Status code reply
*/
public String ltrim(final byte[] key, final long start, final long end) {
checkIsInMultiOrPipeline();
client.ltrim(key, start, end);
return client.getStatusCodeReply();
}
/**
* 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 Bulk reply, specifically the requested element
*/
public byte[] lindex(final byte[] key, final long index) {
checkIsInMultiOrPipeline();
client.lindex(key, index);
return client.getBinaryBulkReply();
}
/**
* 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 #lindex(byte[], long)
* @param key
* @param index
* @param value
* @return Status code reply
*/
public String lset(final byte[] key, final long index, final byte[] value) {
checkIsInMultiOrPipeline();
client.lset(key, index, value);
return client.getStatusCodeReply();
}
/**
* 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 have 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 Integer Reply, specifically: The number of removed elements if the operation succeeded
*/
public Long lrem(final byte[] key, final long count, final byte[] value) {
checkIsInMultiOrPipeline();
client.lrem(key, count, value);
return client.getIntegerReply();
}
/**
* 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 #rpop(byte[])
* @param key
* @return Bulk reply
*/
public byte[] lpop(final byte[] key) {
checkIsInMultiOrPipeline();
client.lpop(key);
return client.getBinaryBulkReply();
}
/**
* 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 #lpop(byte[])
* @param key
* @return Bulk reply
*/
public byte[] rpop(final byte[] key) {
checkIsInMultiOrPipeline();
client.rpop(key);
return client.getBinaryBulkReply();
}
/**
* 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 pusing 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
*/
public byte[] rpoplpush(final byte[] srckey, final byte[] dstkey) {
checkIsInMultiOrPipeline();
client.rpoplpush(srckey, dstkey);
return client.getBinaryBulkReply();
}
/**
* 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 Integer reply, specifically: 1 if the new element was added 0 if the element was
* already a member of the set
*/
public Long sadd(final byte[] key, final byte[]... members) {
checkIsInMultiOrPipeline();
client.sadd(key, members);
return client.getIntegerReply();
}
/**
* Return all the members (elements) of the set value stored at key. This is just syntax glue for
* {@link #sinter(byte[]...)} SINTER}.
*
* Time complexity O(N)
* @param key the key of the set
* @return Multi bulk reply
*/
public Set smembers(final byte[] key) {
checkIsInMultiOrPipeline();
client.smembers(key);
return SetFromList.of(client.getBinaryMultiBulkReply());
}
/**
* 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 member the set member to remove
* @return Integer reply, specifically: 1 if the new element was removed 0 if the new element was
* not a member of the set
*/
public Long srem(final byte[] key, final byte[]... member) {
checkIsInMultiOrPipeline();
client.srem(key, member);
return client.getIntegerReply();
}
/**
* 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 #srandmember(byte[])} command does a similar work but the returned element is not
* removed from the Set.
*
* Time complexity O(1)
* @param key
* @return Bulk reply
*/
public byte[] spop(final byte[] key) {
checkIsInMultiOrPipeline();
client.spop(key);
return client.getBinaryBulkReply();
}
public Set spop(final byte[] key, final long count) {
checkIsInMultiOrPipeline();
client.spop(key, count);
return SetFromList.of(client.getBinaryMultiBulkReply());
}
/**
* 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 Integer reply, specifically: 1 if the element was moved 0 if the element was not found
* on the first set and no operation was performed
*/
public Long smove(final byte[] srckey, final byte[] dstkey, final byte[] member) {
checkIsInMultiOrPipeline();
client.smove(srckey, dstkey, member);
return client.getIntegerReply();
}
/**
* Return the set cardinality (number of elements). If the key does not exist 0 is returned, like
* for empty sets.
* @param key
* @return Integer reply, specifically: the cardinality (number of elements) of the set as an
* integer.
*/
public Long scard(final byte[] key) {
checkIsInMultiOrPipeline();
client.scard(key);
return client.getIntegerReply();
}
/**
* Return 1 if member is a member of the set stored at key, otherwise 0 is returned.
*
* Time complexity O(1)
* @param key
* @param member
* @return Integer reply, specifically: 1 if the element is a member of the set 0 if the element
* is not a member of the set OR if the key does not exist
*/
public Boolean sismember(final byte[] key, final byte[] member) {
checkIsInMultiOrPipeline();
client.sismember(key, member);
return client.getIntegerReply() == 1;
}
/**
* Return the members of a set resulting from the intersection of all the sets hold at the
* specified keys. Like in {@link #lrange(byte[], long, long)} LRANGE} the result is sent to the
* client 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 #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 Multi bulk reply, specifically the list of common elements.
*/
public Set sinter(final byte[]... keys) {
checkIsInMultiOrPipeline();
client.sinter(keys);
return SetFromList.of(client.getBinaryMultiBulkReply());
}
/**
* This commnad works exactly like {@link #sinter(byte[]...) SINTER} but instead of being returned
* the resulting set is sotred 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 Status code reply
*/
public Long sinterstore(final byte[] dstkey, final byte[]... keys) {
checkIsInMultiOrPipeline();
client.sinterstore(dstkey, keys);
return client.getIntegerReply();
}
/**
* Return the members of a set resulting from the union of all the sets hold at the specified
* keys. Like in {@link #lrange(byte[], long, long)} LRANGE} the result is sent to the client 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 #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 Multi bulk reply, specifically the list of common elements.
*/
public Set sunion(final byte[]... keys) {
checkIsInMultiOrPipeline();
client.sunion(keys);
return SetFromList.of(client.getBinaryMultiBulkReply());
}
/**
* This command works exactly like {@link #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 Status code reply
*/
public Long sunionstore(final byte[] dstkey, final byte[]... keys) {
checkIsInMultiOrPipeline();
client.sunionstore(dstkey, keys);
return client.getIntegerReply();
}
/**
* 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 Return the members of a set resulting from the difference between the first set
* provided and all the successive sets.
*/
public Set sdiff(final byte[]... keys) {
checkIsInMultiOrPipeline();
client.sdiff(keys);
return SetFromList.of(client.getBinaryMultiBulkReply());
}
/**
* This command works exactly like {@link #sdiff(byte[]...) SDIFF} but instead of being returned
* the resulting set is stored in dstkey.
* @param dstkey
* @param keys
* @return Status code reply
*/
public Long sdiffstore(final byte[] dstkey, final byte[]... keys) {
checkIsInMultiOrPipeline();
client.sdiffstore(dstkey, keys);
return client.getIntegerReply();
}
/**
* 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 Bulk reply
*/
public byte[] srandmember(final byte[] key) {
checkIsInMultiOrPipeline();
client.srandmember(key);
return client.getBinaryBulkReply();
}
public List srandmember(final byte[] key, final int count) {
checkIsInMultiOrPipeline();
client.srandmember(key, count);
return client.getBinaryMultiBulkReply();
}
/**
* Insert the pairs (timestamp, value) into the map stored at key. TSADD replaces old values with
* new values.
*
* If key does not exist, a new key holding a map is created.
*
* Time complexity: O(N) (with N being the number of timestamps)
* @param key
* @param timeseries
* @return Status code reply
*/
public String tsadd(final byte[] key, final Map timeseries) {
checkIsInMultiOrPipeline();
client.tsadd(key, timeseries);
return client.getStatusCodeReply();
}
/**
* Insert the pairs (timestamp, value) into the map stored at key. TSADD replaces old values with
* new values. If expire_cmd is EXPIRE_IN, the pair (timestamp, value) will be purged after
* expire_time seconds. If expire_cmd is EXPIRE_AT, expire_time will be interpreted as a Unix
* timestamp (seconds since January 1, 1970), and the pair (timestamp, value) will be expire at
* the specified unix time.
*
* If key does not exist, a new key holding a map is created.
*
* Time complexity: O(N) (with N being the number of timestamps)
* @param key
* @param timeseries
* @param expire_cmd
* @param expire_time
* @return Status code reply
*/
public String tsadd(final byte[] key, final Map timeseries,
final byte[] expire_cmd, final byte[] expire_time) {
checkIsInMultiOrPipeline();
client.tsadd(key, timeseries, expire_cmd, expire_time);
return client.getStatusCodeReply();
}
/**
* Retrieve the value associated with the pair (key, timestamp) if it exists.
*
* If the timestamp is not found or the key does not exist, a special 'nil' value is returned.
*
* Time complexity: O(1)
* @param key
* @param timestamp
* @return Bulk reply
*/
@Override
public byte[] tsget(final byte[] key, final byte[] timestamp) {
checkIsInMultiOrPipeline();
client.tsget(key, timestamp);
return client.getBinaryBulkReply();
}
/**
* Removes the timestamp and its associated value if it exists.
*
* Time complexity: O(1)
* @param key
* @param timestamps
* @return Status code reply
*/
@Override
public byte[] tsrem(final byte[] key, final byte[]... timestamps) {
checkIsInMultiOrPipeline();
client.tsrem(key, timestamps);
return client.getBinaryBulkReply();
}
/**
* Return the latest N elements in the given time series.
*
* Time complexity:
*
* O(M) with M being the number of elements returned by the command.
* @param key
* @param limit the number of elements to return
* @return Multi bulk reply with a list of latest N elements.
* Note that the list contains an even number of elements. The elements with an even index are the
* timestamps and the elements with an odd index following them are the associated values. For
* example: [10, "v1", 20, "v2", 30, "v3].
*/
public List tsLastN(final byte[] key, final byte[] limit) {
checkIsInMultiOrPipeline();
client.tsLastN(key, limit);
return client.getBinaryMultiBulkReply();
}
/**
* Return all the elements in the map stored at key with a timestamp between min and max
* (including elements with a timestamp equal to min or max).
*
* 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 timestamp".
*
* Also while the interval is for default closed (inclusive) it's possible to specify open
* intervals prefixing the timestamp with a "(" character, so for instance:
*
* {@code TSRANGEBYTIME k (1 3}
*
* Will return all the values with timestamp > 1 and <= 3, while for
* instance:
*
* {@code TSRANGEBYTIME k (5 (10}
*
* Will return all the values with timestamp > 5 and < 10 (5 and 10 excluded).
*
* Time complexity:
*
* O(M) with M being the number of elements returned by the command.
* @see #tsrangeByTime(byte[], long, long)
* @see #tsrangeByTime(byte[], byte[], byte[])
* @param key
* @param min
* @param max
* @return Multi bulk reply specifically a list of elements in the specified timestamp range.
* Note that the list contains an even number of elements. The elements with an even index are the
* timestamps and the elements with an odd index following them are the associated values. For
* example: [10, "v1", 20, "v2", 30, "v3].
*/
public List tsrangeByTime(final byte[] key, final long min, final long max) {
return tsrangeByTime(key, toByteArray(min), toByteArray(max));
}
public List tsrangeByTime(final byte[] key, final byte[] min, final byte[] max) {
checkIsInMultiOrPipeline();
client.tsrangeByTime(key, min, max);
return client.getBinaryMultiBulkReply();
}
/**
* 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 crated. 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 Integer reply, specifically: 1 if the new element was added 0 if the element was
* already a member of the sorted set and the score was updated
*/
public Long zadd(final byte[] key, final double score, final byte[] member) {
checkIsInMultiOrPipeline();
client.zadd(key, score, member);
return client.getIntegerReply();
}
@Override
public Long zadd(byte[] key, double score, byte[] member, ZAddParams params) {
checkIsInMultiOrPipeline();
client.zadd(key, score, member, params);
return client.getIntegerReply();
}
@Override
public Long zadd(final byte[] key, final Map scoreMembers) {
checkIsInMultiOrPipeline();
client.zaddBinary(key, scoreMembers);
return client.getIntegerReply();
}
@Override
public Long zadd(byte[] key, Map scoreMembers, ZAddParams params) {
checkIsInMultiOrPipeline();
client.zaddBinary(key, scoreMembers, params);
return client.getIntegerReply();
}
@Override
public Set zrange(final byte[] key, final long start, final long end) {
checkIsInMultiOrPipeline();
client.zrange(key, start, end);
return SetFromList.of(client.getBinaryMultiBulkReply());
}
/**
* 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 Integer reply, specifically: 1 if the new element was removed 0 if the new element was
* not a member of the set
*/
public Long zrem(final byte[] key, final byte[]... members) {
checkIsInMultiOrPipeline();
client.zrem(key, members);
return client.getIntegerReply();
}
/**
* 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 crated. 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 score
* @param member
* @return The new score
*/
public Double zincrby(final byte[] key, final double score, final byte[] member) {
checkIsInMultiOrPipeline();
client.zincrby(key, score, member);
String newscore = client.getBulkReply();
return Double.valueOf(newscore);
}
@Override
public Double zincrby(byte[] key, double score, byte[] member, ZIncrByParams params) {
checkIsInMultiOrPipeline();
client.zincrby(key, score, member, params);
String newscore = client.getBulkReply();
// with nx / xx options it could return null now
if (newscore == null) return null;
return Double.valueOf(newscore);
}
/**
* 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 #zrevrank(byte[], byte[])
* @param key
* @param member
* @return Integer reply or a nil bulk reply, specifically: the rank of the element as an integer
* reply if the element exists. A nil bulk reply if there is no such element.
*/
public Long zrank(final byte[] key, final byte[] member) {
checkIsInMultiOrPipeline();
client.zrank(key, member);
return client.getIntegerReply();
}
/**
* 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 #zrank(byte[], byte[])
* @param key
* @param member
* @return Integer reply or a nil bulk reply, specifically: the rank of the element as an integer
* reply if the element exists. A nil bulk reply if there is no such element.
*/
public Long zrevrank(final byte[] key, final byte[] member) {
checkIsInMultiOrPipeline();
client.zrevrank(key, member);
return client.getIntegerReply();
}
public Set zrevrange(final byte[] key, final long start, final long end) {
checkIsInMultiOrPipeline();
client.zrevrange(key, start, end);
return SetFromList.of(client.getBinaryMultiBulkReply());
}
public Set zrangeWithScores(final byte[] key, final long start, final long end) {
checkIsInMultiOrPipeline();
client.zrangeWithScores(key, start, end);
return getBinaryTupledSet();
}
public Set zrevrangeWithScores(final byte[] key, final long start, final long end) {
checkIsInMultiOrPipeline();
client.zrevrangeWithScores(key, start, end);
return getBinaryTupledSet();
}
/**
* 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.
*/
public Long zcard(final byte[] key) {
checkIsInMultiOrPipeline();
client.zcard(key);
return client.getIntegerReply();
}
/**
* Return the sorted set cardinality (number of elements). If the key does not exist 0 is
* returned, like for time series.
*
* Time complexity O(1)
* @param key
* @return the cardinality (number of elements) of the time series as an integer.
*/
public Long tscard(final byte[] key) {
checkIsInMultiOrPipeline();
client.tscard(key);
return client.getIntegerReply();
}
/**
* 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
*/
public Double zscore(final byte[] key, final byte[] member) {
checkIsInMultiOrPipeline();
client.zscore(key, member);
final String score = client.getBulkReply();
return (score != null ? new Double(score) : null);
}
public Transaction multi() {
client.multi();
transaction = new Transaction(client);
return transaction;
}
@Deprecated
/**
* This method is deprecated due to its error prone
* and will be removed on next major release
* You can use multi() instead
* @see https://github.com/xetorthio/jedis/pull/498
*/
public List