mirror of
https://github.com/fluencelabs/redis
synced 2025-03-19 09:00:51 +00:00
client libraries updated
This commit is contained in:
parent
df3fd8d88d
commit
111d9959c0
@ -30,7 +30,6 @@
|
|||||||
:requests)
|
:requests)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defmacro defbenchmark [name & body]
|
(defmacro defbenchmark [name & body]
|
||||||
(let [benchmark-name (symbol (str name "-benchmark"))]
|
(let [benchmark-name (symbol (str name "-benchmark"))]
|
||||||
`(def ~(with-meta benchmark-name {:benchmark true})
|
`(def ~(with-meta benchmark-name {:benchmark true})
|
||||||
@ -64,7 +63,7 @@
|
|||||||
(redis/get (str "key-" (rand-int 1000))))
|
(redis/get (str "key-" (rand-int 1000))))
|
||||||
|
|
||||||
(defbenchmark set
|
(defbenchmark set
|
||||||
(redis/set (str "key-" (rand-int 1000)) "blahojga!"))
|
(redis/set (str "key-" (rand-int 1000)) "abc"))
|
||||||
|
|
||||||
(defbenchmark exists-set-and-get
|
(defbenchmark exists-set-and-get
|
||||||
(let [key (str "key-" (rand-int 100))]
|
(let [key (str "key-" (rand-int 100))]
|
||||||
@ -77,7 +76,7 @@
|
|||||||
:host "127.0.0.1"
|
:host "127.0.0.1"
|
||||||
:port 6379
|
:port 6379
|
||||||
:db 15
|
:db 15
|
||||||
:clients 4
|
:clients 1
|
||||||
:requests 10000))
|
:requests 10000))
|
||||||
|
|
||||||
(defn create-clients [options]
|
(defn create-clients [options]
|
||||||
@ -103,9 +102,14 @@
|
|||||||
(defn report-request-times [clients requests]
|
(defn report-request-times [clients requests]
|
||||||
(let [requests-dist (map #(let [perc (* 100 (/ (last %) requests))]
|
(let [requests-dist (map #(let [perc (* 100 (/ (last %) requests))]
|
||||||
(conj % perc)) (requests-by-ms clients))]
|
(conj % perc)) (requests-by-ms clients))]
|
||||||
(dorun
|
(loop [items requests-dist
|
||||||
(map #(println (format "%.2f%% < %d ms" (float (last %)) (inc (first %))))
|
seen 0]
|
||||||
requests-dist))))
|
(if-not (empty? items)
|
||||||
|
(do
|
||||||
|
(let [item (first items)
|
||||||
|
seen (+ seen (last item))]
|
||||||
|
(println (format "%.2f%% < %d ms" (float seen) (inc (first item))))
|
||||||
|
(recur (rest items) seen)))))))
|
||||||
|
|
||||||
(defn report-client-rps [client]
|
(defn report-client-rps [client]
|
||||||
(let [{:keys [id requests-performed request-times]} @client]
|
(let [{:keys [id requests-performed request-times]} @client]
|
||||||
@ -128,7 +132,7 @@
|
|||||||
(println (format "====== %s =====\n" name))
|
(println (format "====== %s =====\n" name))
|
||||||
(println (format " %d requests completed in %f seconds\n" requests time-in-seconds))
|
(println (format " %d requests completed in %f seconds\n" requests time-in-seconds))
|
||||||
(println (format " %d parallel clients\n" (:clients options)))
|
(println (format " %d parallel clients\n" (:clients options)))
|
||||||
;(report-request-times clients requests)
|
(report-request-times clients requests)
|
||||||
;(dorun (map report-client-rps clients))
|
;(dorun (map report-client-rps clients))
|
||||||
(println (format "%f requests per second\n\n" requests-per-second))
|
(println (format "%f requests per second\n\n" requests-per-second))
|
||||||
)
|
)
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
(ns benchmarks.ruby
|
(ns benchmarks.ruby
|
||||||
(:require redis))
|
(:require redis))
|
||||||
|
|
||||||
|
(dotimes [n 4]
|
||||||
(dotimes [n 2]
|
|
||||||
(redis/with-server
|
(redis/with-server
|
||||||
{}
|
{:db 15}
|
||||||
(redis/set "foo" "The first line we sent to the server is some text")
|
(redis/set "foo" "The first line we sent to the server is some text")
|
||||||
(time
|
(time
|
||||||
(dotimes [i 20000]
|
(dotimes [i 20000]
|
||||||
|
@ -38,8 +38,8 @@
|
|||||||
<target name="jar" description="Create jar file" depends="compile">
|
<target name="jar" description="Create jar file" depends="compile">
|
||||||
<jar jarfile="${redis-clojure.jar}">
|
<jar jarfile="${redis-clojure.jar}">
|
||||||
<path location="LICENSE"/>
|
<path location="LICENSE"/>
|
||||||
<fileset dir="${source.dir}" includes="**/*.clj"/>
|
<!--<fileset dir="${source.dir}" includes="**/*.clj"/>-->
|
||||||
<!--<fileset dir="${build.dir}" includes="**/*.class"/>-->
|
<fileset dir="${build.dir}" includes="**/*.class"/>
|
||||||
<manifest>
|
<manifest>
|
||||||
<attribute name="Built-By" value="${user.name}"/>
|
<attribute name="Built-By" value="${user.name}"/>
|
||||||
</manifest>
|
</manifest>
|
||||||
@ -65,6 +65,7 @@
|
|||||||
<classpath>
|
<classpath>
|
||||||
<path location="${basedir}"/>
|
<path location="${basedir}"/>
|
||||||
<path location="${source.dir}"/>
|
<path location="${source.dir}"/>
|
||||||
|
<!--<path location="${redis-clojure.jar}"/>-->
|
||||||
<path location="${clojure.jar}"/>
|
<path location="${clojure.jar}"/>
|
||||||
<path location="${clojure-contrib.jar}"/>
|
<path location="${clojure-contrib.jar}"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
;(add-classpath "file:///Users/ragge/Projects/clojure/redis-clojure/src/")
|
;(add-classpath "file:///Users/ragge/Projects/clojure/redis-clojure/src/")
|
||||||
|
|
||||||
(set! *warn-on-reflection* true)
|
|
||||||
|
|
||||||
(ns redis
|
(ns redis
|
||||||
(:refer-clojure :exclude [get set type keys sort])
|
(:refer-clojure :exclude [get set type keys sort])
|
||||||
(:use redis.internal))
|
(:use redis.internal))
|
||||||
|
|
||||||
|
;(set! *warn-on-reflection* true)
|
||||||
|
|
||||||
(defmacro with-server
|
(defmacro with-server
|
||||||
"Evaluates body in the context of a new connection to a Redis server
|
"Evaluates body in the context of a new connection to a Redis server
|
||||||
then closes the connection.
|
then closes the connection.
|
||||||
@ -100,6 +100,7 @@
|
|||||||
;; Set commands
|
;; Set commands
|
||||||
(sadd [key member] :bulk int-to-bool)
|
(sadd [key member] :bulk int-to-bool)
|
||||||
(srem [key member] :bulk int-to-bool)
|
(srem [key member] :bulk int-to-bool)
|
||||||
|
(spop [key] :inline)
|
||||||
(smove [srckey destkey member] :bulk int-to-bool)
|
(smove [srckey destkey member] :bulk int-to-bool)
|
||||||
(scard [key] :inline)
|
(scard [key] :inline)
|
||||||
(sismember [key member] :bulk int-to-bool)
|
(sismember [key member] :bulk int-to-bool)
|
||||||
@ -122,6 +123,7 @@
|
|||||||
(bgsave [] :inline)
|
(bgsave [] :inline)
|
||||||
(lastsave [] :inline int-to-date)
|
(lastsave [] :inline int-to-date)
|
||||||
(shutdown [] :inline)
|
(shutdown [] :inline)
|
||||||
|
;; Remote control
|
||||||
(info [] :inline string-to-map)
|
(info [] :inline string-to-map)
|
||||||
;;(monitor [] :inline))
|
;;(monitor [] :inline))
|
||||||
)
|
)
|
||||||
|
@ -39,7 +39,8 @@
|
|||||||
(let [{:keys [host port timeout]} server
|
(let [{:keys [host port timeout]} server
|
||||||
socket (Socket. #^String host #^Integer port)]
|
socket (Socket. #^String host #^Integer port)]
|
||||||
(doto socket
|
(doto socket
|
||||||
(.setTcpNoDelay true))))
|
(.setTcpNoDelay true)
|
||||||
|
(.setKeepAlive true))))
|
||||||
|
|
||||||
(defn with-server*
|
(defn with-server*
|
||||||
[server-spec func]
|
[server-spec func]
|
||||||
@ -99,8 +100,7 @@
|
|||||||
|
|
||||||
(defn reply-type
|
(defn reply-type
|
||||||
([#^BufferedReader reader]
|
([#^BufferedReader reader]
|
||||||
(let [type (char (.read reader))]
|
(char (.read reader))))
|
||||||
type)))
|
|
||||||
|
|
||||||
(defmulti parse-reply reply-type :default :unknown)
|
(defmulti parse-reply reply-type :default :unknown)
|
||||||
|
|
||||||
|
@ -214,20 +214,25 @@
|
|||||||
(redis/lset "list" -1 "test3")
|
(redis/lset "list" -1 "test3")
|
||||||
(is (= "test3" (redis/lindex "list" 2))))
|
(is (= "test3" (redis/lindex "list" 2))))
|
||||||
|
|
||||||
|
|
||||||
;; TBD
|
|
||||||
(deftest lrem
|
(deftest lrem
|
||||||
(is (thrown? Exception (redis/lrem "foo" 0 "bar")))
|
(is (thrown? Exception (redis/lrem "foo" 0 "bar")))
|
||||||
(is (= 0 (redis/lrem "list" 0 ""))))
|
(is (= 0 (redis/lrem "newlist" 0 "")))
|
||||||
|
(is (= 1 (redis/lrem "list" 1 "two")))
|
||||||
|
(is (= 1 (redis/lrem "list" 42 "three")))
|
||||||
|
(is (= 1 (redis/llen "list"))))
|
||||||
|
|
||||||
|
|
||||||
(deftest lpop
|
(deftest lpop
|
||||||
(is (thrown? Exception (redis/lpop "foo")))
|
(is (thrown? Exception (redis/lpop "foo")))
|
||||||
(is (= "one" (redis/lpop "list"))))
|
(is (= nil (redis/lpop "newlist")))
|
||||||
|
(is (= "one" (redis/lpop "list")))
|
||||||
|
(is (= 2 (redis/llen "list"))))
|
||||||
|
|
||||||
(deftest rpop
|
(deftest rpop
|
||||||
(is (thrown? Exception (redis/rpop "foo")))
|
(is (thrown? Exception (redis/rpop "foo")))
|
||||||
(is (= "three" (redis/rpop "list"))))
|
(is (= nil (redis/rpop "newlist")))
|
||||||
|
(is (= "three" (redis/rpop "list")))
|
||||||
|
(is (= 2 (redis/llen "list"))))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Set commands
|
;; Set commands
|
||||||
@ -242,11 +247,16 @@
|
|||||||
|
|
||||||
(deftest srem
|
(deftest srem
|
||||||
(is (thrown? Exception (redis/srem "foo" "bar")))
|
(is (thrown? Exception (redis/srem "foo" "bar")))
|
||||||
(is (thrown? Exception (redis/srem "newset" "member")))
|
(is (= false (redis/srem "newset" "member")))
|
||||||
(is (= true (redis/srem "set" "two")))
|
(is (= true (redis/srem "set" "two")))
|
||||||
(is (= false (redis/sismember "set" "two")))
|
(is (= false (redis/sismember "set" "two")))
|
||||||
(is (= false (redis/srem "set" "blahonga"))))
|
(is (= false (redis/srem "set" "blahonga"))))
|
||||||
|
|
||||||
|
(deftest spop
|
||||||
|
(is (thrown? Exception (redis/spop "foo" "bar")))
|
||||||
|
(is (= nil (redis/spop "newset")))
|
||||||
|
(is (contains? #{"one" "two" "three"} (redis/spop "set"))))
|
||||||
|
|
||||||
(deftest smove
|
(deftest smove
|
||||||
(is (thrown? Exception (redis/smove "foo" "set" "one")))
|
(is (thrown? Exception (redis/smove "foo" "set" "one")))
|
||||||
(is (thrown? Exception (redis/smove "set" "foo" "one")))
|
(is (thrown? Exception (redis/smove "set" "foo" "one")))
|
||||||
|
@ -4,11 +4,6 @@
|
|||||||
(:import [java.io StringReader BufferedReader]))
|
(:import [java.io StringReader BufferedReader]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Helpers
|
;; Helpers
|
||||||
;;
|
;;
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
|
general:
|
||||||
|
- check for complete support for 0.100 (compiles; existing tests pass)
|
||||||
|
|
||||||
command handlers:
|
command handlers:
|
||||||
- support DEL as vararg
|
- support DEL as vararg
|
||||||
- support MLLEN and MSCARD
|
- support MLLEN and MSCARD
|
||||||
|
- support SDIFF
|
||||||
|
- support SDIFFSTORE
|
||||||
|
|
||||||
|
|
||||||
unit tests:
|
unit tests:
|
||||||
- sort with limit
|
- sort with limit
|
||||||
|
@ -40,7 +40,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdlib>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <sys/errno.h>
|
#include <sys/errno.h>
|
||||||
@ -236,32 +235,15 @@ namespace
|
|||||||
return rtrim(line, CRLF);
|
return rtrim(line, CRLF);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long unsigned_number_from_string(const string & data)
|
template <typename T>
|
||||||
|
T value_from_string(const string & data)
|
||||||
{
|
{
|
||||||
errno = 0;
|
T value;
|
||||||
|
|
||||||
unsigned long value = strtoul(data.c_str(), NULL, 10);
|
istringstream iss(data);
|
||||||
|
iss >> value;
|
||||||
if (value == ULONG_MAX && errno == ERANGE)
|
if (iss.fail())
|
||||||
throw redis::value_error("invalid number; out of range of long");
|
throw redis::value_error("invalid number");
|
||||||
|
|
||||||
if (value == 0 && errno == EINVAL)
|
|
||||||
throw redis::value_error("invalid number; unrecognized format");
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
redis::client::int_type number_from_string(const string & data)
|
|
||||||
{
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
redis::client::int_type value = strtol(data.c_str(), NULL, 10);
|
|
||||||
|
|
||||||
if ((value == LONG_MAX || value == LONG_MIN) && errno == ERANGE)
|
|
||||||
throw redis::value_error("invalid number; out of range of long");
|
|
||||||
|
|
||||||
if (value == 0 && errno == EINVAL)
|
|
||||||
throw redis::value_error("invalid number; unrecognized format");
|
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -284,6 +266,10 @@ namespace
|
|||||||
const string server_info_key_total_commands_processed = "total_commands_processed";
|
const string server_info_key_total_commands_processed = "total_commands_processed";
|
||||||
const string server_info_key_uptime_in_seconds = "uptime_in_seconds";
|
const string server_info_key_uptime_in_seconds = "uptime_in_seconds";
|
||||||
const string server_info_key_uptime_in_days = "uptime_in_days";
|
const string server_info_key_uptime_in_days = "uptime_in_days";
|
||||||
|
const string server_info_key_role = "role";
|
||||||
|
|
||||||
|
const string server_info_value_role_master = "master";
|
||||||
|
const string server_info_value_role_slave = "slave";
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace redis
|
namespace redis
|
||||||
@ -578,11 +564,11 @@ namespace redis
|
|||||||
return recv_multi_bulk_reply_(out);
|
return recv_multi_bulk_reply_(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void client::sinterstore(const client::string_type & dstkey,
|
client::int_type client::sinterstore(const client::string_type & dstkey,
|
||||||
const client::string_vector & keys)
|
const client::string_vector & keys)
|
||||||
{
|
{
|
||||||
send_(makecmd("SINTERSTORE") << dstkey << ' ' << keys);
|
send_(makecmd("SINTERSTORE") << dstkey << ' ' << keys);
|
||||||
recv_ok_reply_();
|
return recv_int_reply_();
|
||||||
}
|
}
|
||||||
|
|
||||||
client::int_type client::sunion(const client::string_vector & keys,
|
client::int_type client::sunion(const client::string_vector & keys,
|
||||||
@ -592,11 +578,11 @@ namespace redis
|
|||||||
return recv_multi_bulk_reply_(out);
|
return recv_multi_bulk_reply_(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void client::sunionstore(const client::string_type & dstkey,
|
client::int_type client::sunionstore(const client::string_type & dstkey,
|
||||||
const client::string_vector & keys)
|
const client::string_vector & keys)
|
||||||
{
|
{
|
||||||
send_(makecmd("SUNIONSTORE") << dstkey << ' ' << keys);
|
send_(makecmd("SUNIONSTORE") << dstkey << ' ' << keys);
|
||||||
recv_ok_reply_();
|
return recv_int_reply_();
|
||||||
}
|
}
|
||||||
|
|
||||||
client::int_type client::smembers(const client::string_type & key,
|
client::int_type client::smembers(const client::string_type & key,
|
||||||
@ -746,25 +732,27 @@ namespace redis
|
|||||||
if (key == server_info_key_version)
|
if (key == server_info_key_version)
|
||||||
out.version = val;
|
out.version = val;
|
||||||
else if (key == server_info_key_bgsave_in_progress)
|
else if (key == server_info_key_bgsave_in_progress)
|
||||||
out.bgsave_in_progress = unsigned_number_from_string(val) == 1;
|
out.bgsave_in_progress = value_from_string<unsigned long>(val) == 1;
|
||||||
else if (key == server_info_key_connected_clients)
|
else if (key == server_info_key_connected_clients)
|
||||||
out.connected_clients = unsigned_number_from_string(val);
|
out.connected_clients = value_from_string<unsigned long>(val);
|
||||||
else if (key == server_info_key_connected_slaves)
|
else if (key == server_info_key_connected_slaves)
|
||||||
out.connected_slaves = unsigned_number_from_string(val);
|
out.connected_slaves = value_from_string<unsigned long>(val);
|
||||||
else if (key == server_info_key_used_memory)
|
else if (key == server_info_key_used_memory)
|
||||||
out.used_memory = unsigned_number_from_string(val);
|
out.used_memory = value_from_string<unsigned long>(val);
|
||||||
else if (key == server_info_key_changes_since_last_save)
|
else if (key == server_info_key_changes_since_last_save)
|
||||||
out.changes_since_last_save = unsigned_number_from_string(val);
|
out.changes_since_last_save = value_from_string<unsigned long>(val);
|
||||||
else if (key == server_info_key_last_save_time)
|
else if (key == server_info_key_last_save_time)
|
||||||
out.last_save_time = unsigned_number_from_string(val);
|
out.last_save_time = value_from_string<unsigned long>(val);
|
||||||
else if (key == server_info_key_total_connections_received)
|
else if (key == server_info_key_total_connections_received)
|
||||||
out.total_connections_received = unsigned_number_from_string(val);
|
out.total_connections_received = value_from_string<unsigned long>(val);
|
||||||
else if (key == server_info_key_total_commands_processed)
|
else if (key == server_info_key_total_commands_processed)
|
||||||
out.total_commands_processed = unsigned_number_from_string(val);
|
out.total_commands_processed = value_from_string<unsigned long>(val);
|
||||||
else if (key == server_info_key_uptime_in_seconds)
|
else if (key == server_info_key_uptime_in_seconds)
|
||||||
out.uptime_in_seconds = unsigned_number_from_string(val);
|
out.uptime_in_seconds = value_from_string<unsigned long>(val);
|
||||||
else if (key == server_info_key_uptime_in_days)
|
else if (key == server_info_key_uptime_in_days)
|
||||||
out.uptime_in_days = unsigned_number_from_string(val);
|
out.uptime_in_days = value_from_string<unsigned long>(val);
|
||||||
|
else if (key == server_info_key_role)
|
||||||
|
out.role = val == server_info_value_role_master ? role_master : role_slave;
|
||||||
else
|
else
|
||||||
throw protocol_error(string("unexpected info key '") + key + "'");
|
throw protocol_error(string("unexpected info key '") + key + "'");
|
||||||
}
|
}
|
||||||
@ -826,7 +814,7 @@ namespace redis
|
|||||||
if (line[0] != prefix)
|
if (line[0] != prefix)
|
||||||
throw protocol_error("unexpected prefix for bulk reply");
|
throw protocol_error("unexpected prefix for bulk reply");
|
||||||
|
|
||||||
return number_from_string(line.substr(1));
|
return value_from_string<client::int_type>(line.substr(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
string client::recv_bulk_reply_()
|
string client::recv_bulk_reply_()
|
||||||
@ -895,7 +883,7 @@ namespace redis
|
|||||||
if (line[0] != prefix_int_reply)
|
if (line[0] != prefix_int_reply)
|
||||||
throw protocol_error("unexpected prefix for integer reply");
|
throw protocol_error("unexpected prefix for integer reply");
|
||||||
|
|
||||||
return number_from_string(line.substr(1));
|
return value_from_string<client::int_type>(line.substr(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void client::recv_int_ok_reply_()
|
void client::recv_int_ok_reply_()
|
||||||
|
@ -39,6 +39,12 @@
|
|||||||
|
|
||||||
namespace redis
|
namespace redis
|
||||||
{
|
{
|
||||||
|
enum server_role
|
||||||
|
{
|
||||||
|
role_master,
|
||||||
|
role_slave
|
||||||
|
};
|
||||||
|
|
||||||
struct server_info
|
struct server_info
|
||||||
{
|
{
|
||||||
std::string version;
|
std::string version;
|
||||||
@ -52,6 +58,7 @@ namespace redis
|
|||||||
unsigned long total_commands_processed;
|
unsigned long total_commands_processed;
|
||||||
unsigned long uptime_in_seconds;
|
unsigned long uptime_in_seconds;
|
||||||
unsigned long uptime_in_days;
|
unsigned long uptime_in_days;
|
||||||
|
server_role role;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generic error that is thrown when communicating with the redis server.
|
// Generic error that is thrown when communicating with the redis server.
|
||||||
@ -355,8 +362,9 @@ namespace redis
|
|||||||
|
|
||||||
// Compute the intersection between the sets stored at key1, key2, ...,
|
// Compute the intersection between the sets stored at key1, key2, ...,
|
||||||
// keyN, and store the resulting set at dstkey
|
// keyN, and store the resulting set at dstkey
|
||||||
|
// Returns the number of items in the intersection
|
||||||
|
|
||||||
void sinterstore(const string_type & dstkey, const string_vector & keys);
|
int_type sinterstore(const string_type & dstkey, const string_vector & keys);
|
||||||
|
|
||||||
// Return the union between the sets stored at key1, key2, ..., keyN
|
// Return the union between the sets stored at key1, key2, ..., keyN
|
||||||
|
|
||||||
@ -364,8 +372,9 @@ namespace redis
|
|||||||
|
|
||||||
// Compute the union between the sets stored at key1, key2, ..., keyN,
|
// Compute the union between the sets stored at key1, key2, ..., keyN,
|
||||||
// and store the resulting set at dstkey
|
// and store the resulting set at dstkey
|
||||||
|
// Returns the number of items in the intersection
|
||||||
|
|
||||||
void sunionstore(const string_type & dstkey, const string_vector & keys);
|
int_type sunionstore(const string_type & dstkey, const string_vector & keys);
|
||||||
|
|
||||||
// Return all the members of the set value at key
|
// Return all the members of the set value at key
|
||||||
|
|
||||||
|
@ -478,7 +478,7 @@ int main(int argc, char ** argv)
|
|||||||
keys.push_back("seta");
|
keys.push_back("seta");
|
||||||
keys.push_back("setb");
|
keys.push_back("setb");
|
||||||
|
|
||||||
c.sinterstore("setc", keys);
|
ASSERT_EQUAL(c.sinterstore("setc", keys), 2L);
|
||||||
|
|
||||||
redis::client::string_set members;
|
redis::client::string_set members;
|
||||||
ASSERT_EQUAL(c.smembers("setc", members), 2L);
|
ASSERT_EQUAL(c.smembers("setc", members), 2L);
|
||||||
@ -510,7 +510,7 @@ int main(int argc, char ** argv)
|
|||||||
keys.push_back("setf");
|
keys.push_back("setf");
|
||||||
keys.push_back("setg");
|
keys.push_back("setg");
|
||||||
|
|
||||||
c.sunionstore("seth", keys);
|
ASSERT_EQUAL(c.sunionstore("seth", keys), 2L);
|
||||||
|
|
||||||
redis::client::string_set members;
|
redis::client::string_set members;
|
||||||
ASSERT_EQUAL(c.smembers("seth", members), 2L);
|
ASSERT_EQUAL(c.smembers("seth", members), 2L);
|
||||||
|
@ -239,6 +239,7 @@ redis_commands = {
|
|||||||
set_preserve = bulk('SETNX', toboolean),
|
set_preserve = bulk('SETNX', toboolean),
|
||||||
get = inline('GET'),
|
get = inline('GET'),
|
||||||
get_multiple = inline('MGET'),
|
get_multiple = inline('MGET'),
|
||||||
|
get_set = bulk('GETSET'),
|
||||||
increment = inline('INCR'),
|
increment = inline('INCR'),
|
||||||
increment_by = inline('INCRBY'),
|
increment_by = inline('INCRBY'),
|
||||||
decrement = inline('DECR'),
|
decrement = inline('DECR'),
|
||||||
@ -262,6 +263,7 @@ redis_commands = {
|
|||||||
rename_preserve = inline('RENAMENX'),
|
rename_preserve = inline('RENAMENX'),
|
||||||
expire = inline('EXPIRE', toboolean),
|
expire = inline('EXPIRE', toboolean),
|
||||||
database_size = inline('DBSIZE'),
|
database_size = inline('DBSIZE'),
|
||||||
|
time_to_live = inline('TTL'),
|
||||||
|
|
||||||
-- commands operating on lists
|
-- commands operating on lists
|
||||||
push_tail = bulk('RPUSH'),
|
push_tail = bulk('RPUSH'),
|
||||||
@ -276,12 +278,17 @@ redis_commands = {
|
|||||||
pop_last = inline('RPOP'),
|
pop_last = inline('RPOP'),
|
||||||
|
|
||||||
-- commands operating on sets
|
-- commands operating on sets
|
||||||
set_add = inline('SADD'),
|
set_add = bulk('SADD'),
|
||||||
set_remove = inline('SREM'),
|
set_remove = bulk('SREM'),
|
||||||
|
set_move = bulk('SMOVE'),
|
||||||
set_cardinality = inline('SCARD'),
|
set_cardinality = inline('SCARD'),
|
||||||
set_is_member = inline('SISMEMBER'),
|
set_is_member = inline('SISMEMBER'),
|
||||||
set_intersection = inline('SINTER'),
|
set_intersection = inline('SINTER'),
|
||||||
set_intersection_store = inline('SINTERSTORE'),
|
set_intersection_store = inline('SINTERSTORE'),
|
||||||
|
set_union = inline('SUNION'),
|
||||||
|
set_union_store = inline('SUNIONSTORE'),
|
||||||
|
set_diff = inline('SDIFF'),
|
||||||
|
set_diff_store = inline('SDIFFSTORE'),
|
||||||
set_members = inline('SMEMBERS'),
|
set_members = inline('SMEMBERS'),
|
||||||
|
|
||||||
-- multiple databases handling commands
|
-- multiple databases handling commands
|
||||||
@ -331,4 +338,10 @@ redis_commands = {
|
|||||||
return info
|
return info
|
||||||
end
|
end
|
||||||
),
|
),
|
||||||
|
slave_of = inline('SLAVEOF'),
|
||||||
|
slave_of_no_one = custom('SLAVEOF',
|
||||||
|
function(client, command)
|
||||||
|
return request.inline(client, command, 'NO ONE')
|
||||||
|
end
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
1
client-libraries/ruby/.gitignore
vendored
1
client-libraries/ruby/.gitignore
vendored
@ -2,4 +2,5 @@ nohup.out
|
|||||||
redis/*
|
redis/*
|
||||||
rdsrv
|
rdsrv
|
||||||
pkg/*
|
pkg/*
|
||||||
|
coverage/*
|
||||||
.idea
|
.idea
|
||||||
|
@ -8,7 +8,7 @@ require 'tasks/redis.tasks'
|
|||||||
|
|
||||||
GEM = 'redis'
|
GEM = 'redis'
|
||||||
GEM_NAME = 'redis'
|
GEM_NAME = 'redis'
|
||||||
GEM_VERSION = '0.0.3.4'
|
GEM_VERSION = '0.1'
|
||||||
AUTHORS = ['Ezra Zygmuntowicz', 'Taylor Weibley', 'Matthew Clark']
|
AUTHORS = ['Ezra Zygmuntowicz', 'Taylor Weibley', 'Matthew Clark']
|
||||||
EMAIL = "ez@engineyard.com"
|
EMAIL = "ez@engineyard.com"
|
||||||
HOMEPAGE = "http://github.com/ezmobius/redis-rb"
|
HOMEPAGE = "http://github.com/ezmobius/redis-rb"
|
||||||
@ -54,3 +54,9 @@ task :make_spec do
|
|||||||
file.puts spec.to_ruby
|
file.puts spec.to_ruby
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
desc "Run all examples with RCov"
|
||||||
|
Spec::Rake::SpecTask.new(:rcov) do |t|
|
||||||
|
t.spec_files = FileList['spec/**/*_spec.rb']
|
||||||
|
t.rcov = true
|
||||||
|
end
|
||||||
|
@ -29,7 +29,11 @@ describe "redis" do
|
|||||||
@r.quit
|
@r.quit
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should be able to PING' do
|
it "should be able connect without a timeout" do
|
||||||
|
lambda { Redis.new :timeout => 0 }.should_not raise_error
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should be able to PING" do
|
||||||
@r.ping.should == 'PONG'
|
@r.ping.should == 'PONG'
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -62,6 +66,11 @@ describe "redis" do
|
|||||||
@r['foo'].should == nil
|
@r['foo'].should == nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should be able to return a TTL for a key" do
|
||||||
|
@r.set('foo', 'bar', 1)
|
||||||
|
@r.ttl('foo').should == 1
|
||||||
|
end
|
||||||
|
|
||||||
it "should be able to SETNX" do
|
it "should be able to SETNX" do
|
||||||
@r['foo'] = 'nik'
|
@r['foo'] = 'nik'
|
||||||
@r['foo'].should == 'nik'
|
@r['foo'].should == 'nik'
|
||||||
@ -69,6 +78,11 @@ describe "redis" do
|
|||||||
@r['foo'].should == 'nik'
|
@r['foo'].should == 'nik'
|
||||||
end
|
end
|
||||||
#
|
#
|
||||||
|
it "should be able to GETSET" do
|
||||||
|
@r.getset('foo', 'baz').should == 'bar'
|
||||||
|
@r['foo'].should == 'baz'
|
||||||
|
end
|
||||||
|
#
|
||||||
it "should be able to INCR a key" do
|
it "should be able to INCR a key" do
|
||||||
@r.del('counter')
|
@r.del('counter')
|
||||||
@r.incr('counter').should == 1
|
@r.incr('counter').should == 1
|
||||||
@ -76,6 +90,13 @@ describe "redis" do
|
|||||||
@r.incr('counter').should == 3
|
@r.incr('counter').should == 3
|
||||||
end
|
end
|
||||||
#
|
#
|
||||||
|
it "should be able to INCRBY a key" do
|
||||||
|
@r.del('counter')
|
||||||
|
@r.incrby('counter', 1).should == 1
|
||||||
|
@r.incrby('counter', 2).should == 3
|
||||||
|
@r.incrby('counter', 3).should == 6
|
||||||
|
end
|
||||||
|
#
|
||||||
it "should be able to DECR a key" do
|
it "should be able to DECR a key" do
|
||||||
@r.del('counter')
|
@r.del('counter')
|
||||||
@r.incr('counter').should == 1
|
@r.incr('counter').should == 1
|
||||||
@ -137,6 +158,10 @@ describe "redis" do
|
|||||||
@r['foo'] = 'qux'
|
@r['foo'] = 'qux'
|
||||||
@r.keys("f*").sort.should == ['f','fo', 'foo'].sort
|
@r.keys("f*").sort.should == ['f','fo', 'foo'].sort
|
||||||
end
|
end
|
||||||
|
#
|
||||||
|
it "should be able to return a random key (RANDOMKEY)" do
|
||||||
|
3.times { @r.exists(@r.randomkey).should be_true }
|
||||||
|
end
|
||||||
#BTM - TODO
|
#BTM - TODO
|
||||||
it "should be able to check the TYPE of a key" do
|
it "should be able to check the TYPE of a key" do
|
||||||
@r['foo'] = 'nik'
|
@r['foo'] = 'nik'
|
||||||
@ -356,13 +381,13 @@ describe "redis" do
|
|||||||
@r.sort('dogs', :get => ['dog:*:name', 'dog:*:breed'], :limit => [0,1], :order => 'desc alpha').should == ['taj', 'terrier']
|
@r.sort('dogs', :get => ['dog:*:name', 'dog:*:breed'], :limit => [0,1], :order => 'desc alpha').should == ['taj', 'terrier']
|
||||||
end
|
end
|
||||||
#
|
#
|
||||||
it "should provide info" do
|
it "should provide info (INFO)" do
|
||||||
[:last_save_time, :redis_version, :total_connections_received, :connected_clients, :total_commands_processed, :connected_slaves, :uptime_in_seconds, :used_memory, :uptime_in_days, :changes_since_last_save].each do |x|
|
[:last_save_time, :redis_version, :total_connections_received, :connected_clients, :total_commands_processed, :connected_slaves, :uptime_in_seconds, :used_memory, :uptime_in_days, :changes_since_last_save].each do |x|
|
||||||
@r.info.keys.should include(x)
|
@r.info.keys.should include(x)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
#
|
#
|
||||||
it "should be able to flush the database" do
|
it "should be able to flush the database (FLUSHDB)" do
|
||||||
@r['key1'] = 'keyone'
|
@r['key1'] = 'keyone'
|
||||||
@r['key2'] = 'keytwo'
|
@r['key2'] = 'keytwo'
|
||||||
@r.keys('*').sort.should == ['foo', 'key1', 'key2'].sort #foo from before
|
@r.keys('*').sort.should == ['foo', 'key1', 'key2'].sort #foo from before
|
||||||
@ -370,6 +395,10 @@ describe "redis" do
|
|||||||
@r.keys('*').should == []
|
@r.keys('*').should == []
|
||||||
end
|
end
|
||||||
#
|
#
|
||||||
|
it "should raise exception when manually try to change the database" do
|
||||||
|
lambda { @r.select(0) }.should raise_error
|
||||||
|
end
|
||||||
|
#
|
||||||
it "should be able to provide the last save time (LASTSAVE)" do
|
it "should be able to provide the last save time (LASTSAVE)" do
|
||||||
savetime = @r.lastsave
|
savetime = @r.lastsave
|
||||||
Time.at(savetime).class.should == Time
|
Time.at(savetime).class.should == Time
|
||||||
@ -387,6 +416,10 @@ describe "redis" do
|
|||||||
@r.bgsave.should == 'OK'
|
@r.bgsave.should == 'OK'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should should be able to ECHO" do
|
||||||
|
@r.echo("message in a bottle\n").should == "message in a bottle\n"
|
||||||
|
end
|
||||||
|
|
||||||
it "should handle multiple servers" do
|
it "should handle multiple servers" do
|
||||||
require 'dist_redis'
|
require 'dist_redis'
|
||||||
@r = DistRedis.new(:hosts=> ['localhost:6379', '127.0.0.1:6379'], :db => 15)
|
@r = DistRedis.new(:hosts=> ['localhost:6379', '127.0.0.1:6379'], :db => 15)
|
||||||
|
12
client-libraries/update-clojure-client.sh
Executable file
12
client-libraries/update-clojure-client.sh
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
rm -rf temp
|
||||||
|
mkdir temp
|
||||||
|
cd temp
|
||||||
|
git clone git://github.com/ragnard/redis-clojure.git
|
||||||
|
cd redis-clojure
|
||||||
|
rm -rf .git
|
||||||
|
cd ..
|
||||||
|
cd ..
|
||||||
|
rm -rf clojure
|
||||||
|
mv temp/redis-clojure clojure
|
||||||
|
rm -rf temp
|
Loading…
x
Reference in New Issue
Block a user