summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author郑超 <[email protected]>2024-06-25 08:16:37 +0000
committer郑超 <[email protected]>2024-06-25 08:16:37 +0000
commit19df9685b1e1ae0360c6859626e123dbe863a897 (patch)
tree85cfc36ef794e079966fc089f4b7fa09821084b0
parent4fab21dfa937755238534189755b1c8899bf71a2 (diff)
The Network Layer is easy to read. Compression Ratio is available in network statistics. The recursion of the exec_cmd() is easier to understand. The latency command output is beautified.
-rw-r--r--deps/log/log.h2
-rw-r--r--docs/commands/token_bucket.md4
-rw-r--r--docs/design.md6
-rw-r--r--include/swarmkv/swarmkv.h3
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/swarmkv.c2201
-rw-r--r--src/swarmkv_api.c506
-rw-r--r--src/swarmkv_cmd_spec.c202
-rw-r--r--src/swarmkv_cmd_spec.h14
-rw-r--r--src/swarmkv_common.c842
-rw-r--r--src/swarmkv_common.h1
-rw-r--r--src/swarmkv_core.h6
-rw-r--r--src/swarmkv_keyspace.c1633
-rw-r--r--src/swarmkv_mesh.c160
-rw-r--r--src/swarmkv_mesh.h4
-rw-r--r--src/swarmkv_message.c326
-rw-r--r--src/swarmkv_message.h30
-rw-r--r--src/swarmkv_monitor.c509
-rw-r--r--src/swarmkv_monitor.h2
-rw-r--r--src/swarmkv_net.c698
-rw-r--r--src/swarmkv_net.h8
-rw-r--r--src/swarmkv_rpc.c92
-rw-r--r--src/swarmkv_store.c1025
-rw-r--r--src/swarmkv_sync.c78
-rw-r--r--src/swarmkv_utils.c176
-rw-r--r--src/t_bloom_filter.c236
-rw-r--r--src/t_cms.c350
-rw-r--r--src/t_hash.c362
-rw-r--r--src/t_hyperloglog.c147
-rw-r--r--src/t_set.c153
-rw-r--r--src/t_string.c120
-rw-r--r--src/t_token_bucket.c606
-rw-r--r--test/swarmkv_gtest.cpp104
33 files changed, 5418 insertions, 5190 deletions
diff --git a/deps/log/log.h b/deps/log/log.h
index 285cf5a..18eeafe 100644
--- a/deps/log/log.h
+++ b/deps/log/log.h
@@ -31,7 +31,7 @@ enum { LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL };
#define log_error(handle, module, fmt, ...) log_print(handle, LOG_ERROR, module, fmt, ##__VA_ARGS__)
#define log_fatal(handle, module, fmt, ...) log_print(handle, LOG_FATAL, module, fmt, ##__VA_ARGS__)
-void log_print(struct log_handle *, int level, const char *module, const char *fmt, ...);
+void log_print(struct log_handle *, int level, const char *module, const char *fmt, ...)__attribute__ ((format (printf, 4, 5)));
void log_options_set_enable(struct log_handle *, int enable);
void log_options_set_level(struct log_handle *, int level);
diff --git a/docs/commands/token_bucket.md b/docs/commands/token_bucket.md
index 3926029..6867f73 100644
--- a/docs/commands/token_bucket.md
+++ b/docs/commands/token_bucket.md
@@ -153,9 +153,9 @@ Syntax
BTCFG key rate capacity buckets [PD seconds]
```
-Configure a bulk token bucket for a `key`. In addition to the usual `rate` and `capacity` settings of a normal token bucket, this configuration includes a `buckets` parameter, which specifies the initial number of buckets. The value for `buckets` must be a power of two and should be proportional to the potential number of members; otherwise, it will be expanded by a factor of 2. The optional `PD` parameter sets the token refill period, which defaults to 1 second.
+Configure a bulk token bucket for a `key`. A bulk token bucket holds multiple token buckets of same configuration. It uses cuckoo hashing to resolve key collisions. In addition to the usual `rate` and `capacity` settings of a normal token bucket, this configuration includes a `buckets` parameter, which specifies the initial number of buckets. The value for `buckets` must be a power of two and should be proportional to the potential number of members; otherwise, it will be expanded by a factor of 2. The optional `PD` parameter sets the token refill period, which defaults to 1 second.
-If `key` does not exist, a new key holding a fair token bucket is created.
+If `key` does not exist, a new key holding a bulk token bucket is created.
Return
diff --git a/docs/design.md b/docs/design.md
index be5fa56..f00cf79 100644
--- a/docs/design.md
+++ b/docs/design.md
@@ -231,8 +231,7 @@ Each worker thread reads and writes its own shard of KV store and Keyspace table
<img src="./imgs/thread_model.svg" alt="Thread Model" />
All worker threads are responsible for:
-- Watch global slot table changes.
-- Run periodic tasks.
+- Run periodic synchronization tasks .
- Send command message, which is from swarmkv API caller to destination peers.
- Receive KV command message, and then process it based on command type:
- Key routing request (from the requester, object reader/writer): lookup the object owner, and then send key routing response.
@@ -244,11 +243,12 @@ All worker threads are responsible for:
The worker thread 0 has extra tasks including:
- Accepting TCP connections from other peers. It begins by peeking at the message header to determine the caller thread ID, then it load balances the connection across worker threads using the caller_ID mod worker thread number. This mechanism eliminates unnecessary inter-thread communication for nodes with the same worker thread number.
+- Watch global slot table changes, and update local slot table.
- Watch leadership changes, and run for leader if cluster loses its leader.
- For leader node:
- Watch cluster health check, remove failed node from cluster by assigning its slots to other nodes.
-## Source Code layout
+## Source code layout
The source files are organized as follows:
diff --git a/include/swarmkv/swarmkv.h b/include/swarmkv/swarmkv.h
index c161b2f..69f2fd8 100644
--- a/include/swarmkv/swarmkv.h
+++ b/include/swarmkv/swarmkv.h
@@ -73,6 +73,9 @@ int swarmkv_options_set_caller_thread_number(struct swarmkv_options *opts, int n
int swarmkv_options_set_worker_thread_number(struct swarmkv_options *opts, int nr_worker_threads);
int swarmkv_options_get_worker_thread_number(const struct swarmkv_options *opts);
+//Default 1: Enabled.
+//Enable snappy compression for network communication.
+int swarmkv_options_set_network_compression_enabled(struct swarmkv_options *opts, int value);
/**
* This function has change the behavior of swarmkv_caller_loop().
* Record an interval and/or a number of callbacks after which the event base
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 329295a..8ee7449 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -23,7 +23,7 @@ add_definitions(-DGIT_VERSION=\"${GIT_VERSION}\")
add_definitions(-D_GNU_SOURCE)
add_definitions(-fPIC)
-set(SWARMKV_SRC swarmkv.c swarmkv_api.c
+set(SWARMKV_SRC swarmkv_cmd_spec.c swarmkv.c swarmkv_api.c
swarmkv_mesh.c swarmkv_rpc.c swarmkv_message.c swarmkv_net.c
swarmkv_sync.c swarmkv_store.c swarmkv_keyspace.c swarmkv_monitor.c
t_string.c t_set.c t_token_bucket.c t_hash.c t_bloom_filter.c t_cms.c t_hyperloglog.c
diff --git a/src/swarmkv.c b/src/swarmkv.c
index 5d50d6a..d3013ef 100644
--- a/src/swarmkv.c
+++ b/src/swarmkv.c
@@ -6,19 +6,19 @@
#include "swarmkv_utils.h"
#include "swarmkv_error.h"
-//header of communications
+// header of communications
#include "swarmkv_message.h"
#include "future_promise.h"
#include "swarmkv_rpc.h"
#include "swarmkv_mesh.h"
#include "swarmkv_net.h"
-//header of modules
+// header of modules
#include "swarmkv_store.h"
#include "swarmkv_keyspace.h"
#include "swarmkv_monitor.h"
-//header of data types
+// header of data types
#include "t_string.h"
#include "t_set.h"
#include "t_hash.h"
@@ -37,13 +37,9 @@
#include <sys/syscall.h>
#include <sys/prctl.h>
#include <pthread.h>
-#include <ctype.h>
#include <stdatomic.h>
-
-#define MODULE_SWAMRKV_CORE module_name_str("swarmkv.core")
-
-
+#define MODULE_SWAMRKV_CORE module_name_str("swarmkv.core")
struct swarmkv_thread
{
@@ -58,7 +54,6 @@ struct swarmkv_thread
struct event *store_periodic_ev;
};
-
struct swarmkv
{
struct swarmkv_module module;
@@ -75,46 +70,47 @@ struct swarmkv
struct swarmkv_rpc_mgr *rpc_mgr;
struct swarmkv_mesh *mesh;
struct swarmkv_net *net;
-
struct log_handle *logger;
+
struct swarmkv_module *mod_keyspace;
struct swarmkv_module *mod_store;
struct swarmkv_module *mod_monitor;
- struct swarmkv_cmd_spec *command_table;
+ struct swarmkv_module *mod_command_table;
+
struct timespec boot_time;
- //For statistics
+ // For statistics
long long local_cmds;
long long remote_cmds;
};
struct swarmkv *module2db(struct swarmkv_module *module)
{
- assert(0==strcmp(module->name, "db"));
- struct swarmkv *db=container_of(module, struct swarmkv, module);
- assert(db==module->mod_ctx);
+ assert(0 == strcmp(module->name, "db"));
+ struct swarmkv *db = container_of(module, struct swarmkv, module);
+ assert(db == module->mod_ctx);
return db;
}
-__thread int __sys_tid=-1;
+__thread int __sys_tid = -1;
void swarmkv_register_thread(struct swarmkv *db)
{
int thread_id = atomic_fetch_add(&db->thread_counter, 1);
assert(thread_id < db->opts->nr_worker_threads + db->opts->nr_caller_threads);
- if(__sys_tid<0) __sys_tid=syscall(SYS_gettid);
- db->threads[thread_id].sys_tid=__sys_tid;
- db->threads[thread_id].thread_id=thread_id;
+ if (__sys_tid < 0)
+ __sys_tid = syscall(SYS_gettid);
+ db->threads[thread_id].sys_tid = __sys_tid;
+ db->threads[thread_id].thread_id = thread_id;
return;
}
+static void exec_cmd(struct swarmkv *db, const struct swarmkv_cmd *cmd, struct future *future_of_caller);
struct swarmkv_options *swarmkv_get0_options(struct swarmkv *db)
{
return db->opts;
}
-
int swarmkv_gettid(const struct swarmkv *db)
{
-// int __sys_tid=syscall(SYS_gettid);
- for(int i=0; i<db->opts->nr_worker_threads + db->opts->nr_caller_threads; i++)
+ for (int i = 0; i < db->opts->nr_worker_threads + db->opts->nr_caller_threads; i++)
{
- if(db->threads[i].sys_tid==__sys_tid)
+ if (db->threads[i].sys_tid == __sys_tid)
{
return db->threads[i].thread_id;
}
@@ -122,156 +118,553 @@ int swarmkv_gettid(const struct swarmkv *db)
assert(0);
return -1;
}
-void __exec_cmd(struct swarmkv *db, const node_t *target_node, const struct swarmkv_cmd *cmd, struct future *future_of_caller);
-struct local_caller_ctx
+#define INTER_THREAD_RPC_TIMEOUT_AHEAD 1000
+#define UNKNOWN_THREAD_ID -1
+static void exec_at_peer(struct swarmkv *db, const struct swarmkv_cmd *cmd, const node_t *peer, struct future *future_of_caller)
{
- swarmkv_on_reply_callback_t * cb;
- void * cb_arg;
- struct future *my_future;
+ assert(node_compare(peer, &db->self));
+ // cmd will be executed in target thread's on_msg_callback
+ int cur_tid = swarmkv_gettid(db);
+ struct swarmkv_rpc *rpc = swarmkv_rpc_launch(db->rpc_mgr, cur_tid, future_of_caller);
+ swarmkv_rpc_set_timeout(rpc, db->opts->cluster_timeout_us + INTER_THREAD_RPC_TIMEOUT_AHEAD);
+ long long sequence = swarmkv_rpc_get_sequence(rpc);
+ struct swarmkv_msg *msg = swarmkv_msg_new_by_cmd(cmd, sequence);
+ int ret = 0;
+ const char *err_str = NULL;
+ ret = swarmkv_net_send(db->net, cur_tid, peer, UNKNOWN_THREAD_ID, msg, &err_str);
+ if (ret < 0)
+ {
+ struct swarmkv_reply *reply = swarmkv_reply_new_error(error_network_error, node_addr2cstr(peer), err_str);
+ swarmkv_rpc_complete(db->rpc_mgr, cur_tid, sequence, reply);
+ swarmkv_reply_free(reply);
+ return;
+ }
+ swarmkv_rpc_set_peer(rpc, peer);
+}
+static void exec_at_thread(struct swarmkv *db, const struct swarmkv_cmd *cmd, int tid, struct future *future_of_caller)
+{
+ int cur_tid = swarmkv_gettid(db);
+ assert(cur_tid != tid);
+ struct swarmkv_rpc *rpc = swarmkv_rpc_launch(db->rpc_mgr, cur_tid, future_of_caller);
+ long long sequence = swarmkv_rpc_get_sequence(rpc);
+ struct swarmkv_msg *msg = swarmkv_msg_new_by_cmd(cmd, sequence);
+ int ret = 0;
+
+ // Only worker threads can do network communication, so command should be executed at worker thread first.
+ ret = swarmkv_mesh_send(db->mesh, cur_tid, tid, msg);
+ if (ret < 0)
+ {
+ struct swarmkv_reply *reply = swarmkv_reply_new_error(error_thread_rpc_buffer_full);
+ swarmkv_rpc_complete(db->rpc_mgr, cur_tid, sequence, reply);
+ swarmkv_reply_free(reply);
+ }
+ swarmkv_rpc_set_timeout(rpc, db->opts->cluster_timeout_us + INTER_THREAD_RPC_TIMEOUT_AHEAD);
+}
+static int spec_gettid(const struct swarmkv_cmd_spec *spec, const struct swarmkv_cmd *cmd, int nr_worker_threads)
+{
+ int tid = 0;
+ switch (spec->key_offset)
+ {
+ case KEY_OFFSET_TID:
+ tid = atoi(cmd->argv[2]);
+ break;
+ case KEY_OFFSET_SLOTID:
+ tid = swarmkv_keyspace_slot2tid(spec->module, atoi(cmd->argv[2]));
+ break;
+ default:
+ tid = key2tid(cmd->argv[spec->key_offset], nr_worker_threads);
+ break;
+ }
+ return tid;
+}
+
+static struct swarmkv_reply *key_not_found_reply(enum key_not_found_reply not_found_flag)
+{
+ struct swarmkv_reply *reply = NULL;
+ switch (not_found_flag)
+ {
+ case REPLY_INT_0:
+ reply = swarmkv_reply_new_integer(0);
+ break;
+ case REPLY_INT_MINORS1:
+ reply = swarmkv_reply_new_integer(-1);
+ break;
+ case REPLY_NIL:
+ reply = swarmkv_reply_new_nil();
+ break;
+ case REPLY_EMPTY_ARRAY:
+ reply = swarmkv_reply_new_array(0);
+ break;
+ case REPLY_STR_NONE:
+ reply = swarmkv_reply_new_string_fmt("none");
+ break;
+ case REPLY_ERROR:
+ reply = swarmkv_reply_new_error(error_keyspace_obj_owner_not_found);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ return reply;
+}
+
+static struct swarmkv_cmd *make_keyroute_cmd(enum cmd_key_flag flag, const sds key, int dry_run, const node_t *caller)
+{
+ struct swarmkv_cmd *keyroute_cmd = NULL;
+ switch (flag)
+ {
+ case CMD_KEY_RO:
+ case CMD_KEY_RW:
+ if (!dry_run)
+ {
+ keyroute_cmd = swarmkv_cmd_new(4, caller);
+ keyroute_cmd->argv[0] = sdsnew("keyspace");
+ keyroute_cmd->argv[1] = sdsnew("xradd");
+ keyroute_cmd->argv[2] = sdsdup(key);
+ keyroute_cmd->argv[3] = node_addr2sds(caller);
+ }
+ else
+ {
+ keyroute_cmd = swarmkv_cmd_new(3, caller);
+ keyroute_cmd->argv[0] = sdsnew("keyspace");
+ keyroute_cmd->argv[1] = sdsnew("rlist");
+ keyroute_cmd->argv[2] = sdsdup(key);
+ }
+ break;
+ case CMD_KEY_OW:
+ if (!dry_run)
+ {
+ keyroute_cmd = swarmkv_cmd_new(4, caller);
+ keyroute_cmd->argv[0] = sdsnew("keyspace");
+ keyroute_cmd->argv[1] = sdsnew("radd");
+ keyroute_cmd->argv[2] = sdsdup(key);
+ keyroute_cmd->argv[3] = node_addr2sds(caller);
+ }
+ else
+ {
+ keyroute_cmd = swarmkv_cmd_new(3, caller);
+ keyroute_cmd->argv[0] = sdsnew("keyspace");
+ keyroute_cmd->argv[1] = sdsnew("radd");
+ keyroute_cmd->argv[2] = sdsdup(key);
+ }
+ break;
+ case CMD_KEY_RM:
+ assert(0);
+ keyroute_cmd = swarmkv_cmd_new(3, caller);
+ keyroute_cmd->argv[0] = sdsnew("keyspace");
+ keyroute_cmd->argv[1] = sdsnew("del");
+ keyroute_cmd->argv[2] = sdsdup(key);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ return keyroute_cmd;
+}
+struct cmd_ctx
+{
+ struct swarmkv *db;
+ struct swarmkv_cmd *cmd;
+ int redirect_cnt;
+ struct future *future_of_mine;
+ struct future *future_of_caller;
};
-static void local_caller_on_success(void *result, void *user)
-{
- struct local_caller_ctx *ctx=(struct local_caller_ctx*)user;
- const struct swarmkv_reply *reply=(const struct swarmkv_reply *)result;
- ctx->cb(reply, ctx->cb_arg);
- future_destroy(ctx->my_future);
+
+struct cmd_ctx *cmd_ctx_new(struct swarmkv *db, const struct swarmkv_cmd *cmd, struct future *f)
+{
+ struct cmd_ctx *ctx = ALLOC(struct cmd_ctx, 1);
+ ctx->db = db;
+ ctx->cmd = swarmkv_cmd_dup(cmd);
+ ctx->redirect_cnt = 0;
+ ctx->future_of_caller = f;
+ return ctx;
+}
+void cmd_ctx_free(struct cmd_ctx *ctx)
+{
+ swarmkv_cmd_free(ctx->cmd);
+ future_destroy(ctx->future_of_mine);
free(ctx);
+ return;
+}
+static void generic_on_fail(enum e_future_error err, const char *what, void *user)
+{
+ struct cmd_ctx *ctx = (struct cmd_ctx *)user;
+ if (ctx->future_of_caller)
+ {
+ struct promise *p = future_to_promise(ctx->future_of_caller);
+ promise_failed(p, err, what);
+ }
+ cmd_ctx_free(ctx);
+}
+static void peer_exec_on_success(void *result, void *user)
+{
+ struct cmd_ctx *ctx = (struct cmd_ctx *)user;
+ struct swarmkv_reply *reply = (struct swarmkv_reply *)result;
+
+ if (reply->type == SWARMKV_REPLY_NODE && 0 == strncasecmp(reply->str, "-ASK", 4))
+ {
+ ctx->redirect_cnt++;
+ if (ctx->redirect_cnt <= 3)
+ {
+ node_t target_node;
+ node_init_from_reply(&target_node, reply);
+ exec_at_peer(ctx->db, ctx->cmd, &target_node, ctx->future_of_mine);
+ }
+ else
+ {
+ char err_msg[256];
+ snprintf(err_msg, sizeof(err_msg), error_too_many_redirects, reply->str);
+ struct promise *p = future_to_promise(ctx->future_of_caller);
+ promise_failed(p, FUTURE_ERROR_EXCEPTION, err_msg);
+ cmd_ctx_free(ctx);
+ }
+ }
+ else
+ {
+ struct promise *p = future_to_promise(ctx->future_of_caller);
+ promise_success(p, (void *)reply);
+ cmd_ctx_free(ctx);
+ }
+}
+struct swarmkv_cmd *make_crdt_add_cmd(const sds key, node_t replica[], size_t n_replica, const node_t *caller)
+{
+ struct swarmkv_cmd *crdt_add_cmd = NULL;
+ crdt_add_cmd = swarmkv_cmd_new(3 + n_replica, caller);
+ crdt_add_cmd->argv[0] = sdsnew("crdt");
+ crdt_add_cmd->argv[1] = sdsnew("add");
+ crdt_add_cmd->argv[2] = sdsdup(key);
+ for (size_t i = 0; i < n_replica; i++)
+ {
+ crdt_add_cmd->argv[3 + i] = node_addr2sds(replica + i);
+ }
+ return crdt_add_cmd;
+}
+static void crdt_add_on_success(void *result, void *user)
+{
+ struct swarmkv_reply *reply = (struct swarmkv_reply *)result;
+ struct cmd_ctx *ctx = (struct cmd_ctx *)user;
+ assert(reply->type == SWARMKV_REPLY_STATUS);
+ if (ctx->future_of_caller)
+ {
+ exec_cmd(ctx->db, ctx->cmd, ctx->future_of_caller);
+ }
+ cmd_ctx_free(ctx);
}
-static void local_caller_on_fail(enum e_future_error err, const char * what, void * user)
+static void key_route_on_success(void *result, void *user)
+{
+ struct cmd_ctx *ctx = (struct cmd_ctx *)user;
+ const struct swarmkv_reply *reply = (const struct swarmkv_reply *)result;
+ struct swarmkv_reply *user_reply_for_keyspace_not_found = NULL;
+ size_t n_replica_node = 0;
+ node_t *replica_nodes = NULL;
+ const struct swarmkv_cmd_spec *spec = swarmkv_command_table_get_spec_by_argv(ctx->db->mod_command_table, ctx->cmd->argc, ctx->cmd->argv);
+
+ node_list_new_from_reply(&replica_nodes, &n_replica_node, reply);
+ if (n_replica_node == 0)
+ {
+ user_reply_for_keyspace_not_found = key_not_found_reply(spec->nokey_reply);
+ struct promise *p = future_to_promise(ctx->future_of_caller);
+ promise_success(p, user_reply_for_keyspace_not_found);
+ swarmkv_reply_free(user_reply_for_keyspace_not_found);
+ user_reply_for_keyspace_not_found = NULL;
+ }
+ else
+ {
+ const sds key = ctx->cmd->argv[spec->key_offset];
+ int self_is_a_replica = node_list_exists(replica_nodes, n_replica_node, &ctx->db->self);
+ if (self_is_a_replica)
+ {
+ n_replica_node -= node_list_remove(replica_nodes, n_replica_node, &ctx->db->self);
+ }
+ if (n_replica_node > 0)
+ {
+ exec_at_peer(ctx->db, ctx->cmd, replica_nodes + 0, ctx->future_of_caller);
+ }
+ if (self_is_a_replica)
+ {
+ struct cmd_ctx *crdt_add_ctx = NULL;
+ struct swarmkv_cmd *crdt_add_cmd = make_crdt_add_cmd(key, replica_nodes, n_replica_node, &ctx->db->self);
+ crdt_add_ctx = cmd_ctx_new(ctx->db, ctx->cmd, n_replica_node > 0 ? NULL : ctx->future_of_caller);
+ crdt_add_ctx->future_of_mine = future_create("crdt_add", crdt_add_on_success, generic_on_fail, crdt_add_ctx);
+ exec_cmd(ctx->db, crdt_add_cmd, crdt_add_ctx->future_of_mine);
+ swarmkv_cmd_free(crdt_add_cmd);
+ }
+ free(replica_nodes);
+ }
+ cmd_ctx_free(ctx);
+}
+void exec_cmd(struct swarmkv *db, const struct swarmkv_cmd *cmd, struct future *future_of_caller)
+{
+ const struct swarmkv_cmd_spec *spec = NULL;
+ struct swarmkv_reply *reply = NULL;
+ struct promise *p = NULL;
+ int cur_tid = swarmkv_gettid(db);
+
+ spec = swarmkv_command_table_get_spec_by_argv(db->mod_command_table, cmd->argc, cmd->argv);
+ if (!spec)
+ {
+ reply = swarmkv_reply_new_error(error_unknown_command, cmd->argv[0], cmd->argc > 1 ? cmd->argv[1] : " ");
+ p = future_to_promise(future_of_caller);
+ promise_success(p, reply);
+ swarmkv_reply_free(reply);
+ return;
+ }
+ if (!command_spec_is_sufficient_args(spec, cmd)) // error happens
+ {
+ reply = swarmkv_reply_new_error(error_wrong_number_of_arg, spec->name);
+ p = future_to_promise(future_of_caller);
+ promise_success(p, reply);
+ swarmkv_reply_free(reply);
+ return;
+ }
+ int target_tid = spec_gettid(spec, cmd, db->opts->nr_worker_threads);
+
+ if (cur_tid != target_tid)
+ {
+ // cmd will be executed in target thread's on_msg_callback
+ exec_at_thread(db, cmd, target_tid, future_of_caller);
+ return;
+ }
+
+ db->threads[cur_tid].recusion_depth++;
+ assert(db->threads[cur_tid].recusion_depth < 8);
+ enum cmd_exec_result exec_ret = FINISHED;
+ struct timespec start, end;
+ clock_gettime(CLOCK_MONOTONIC_COARSE, &start);
+ exec_ret = spec->proc(spec->module, cmd, &reply);
+ clock_gettime(CLOCK_MONOTONIC_COARSE, &end);
+ swarmkv_monitor_record_command(db->mod_monitor, spec, cmd, timespec_diff_usec(&start, &end), exec_ret);
+ switch (exec_ret)
+ {
+ case FINISHED:
+ {
+ struct promise *p = future_to_promise(future_of_caller);
+ promise_success(p, reply);
+ swarmkv_reply_free(reply);
+ break;
+ }
+ case REDIRECT:
+ {
+ node_t peer;
+ struct cmd_ctx *ctx = cmd_ctx_new(db, cmd, future_of_caller);
+ ctx->future_of_caller = future_of_caller;
+ node_init_from_reply(&peer, reply);
+ swarmkv_reply_free(reply);
+
+ // Should never redirect to myself
+ assert(node_compare(&peer, &db->self));
+ ctx->future_of_mine = future_create("peer_exec", peer_exec_on_success, generic_on_fail, ctx);
+ exec_at_peer(db, cmd, &peer, ctx->future_of_mine);
+ break;
+ }
+ case NEED_KEY_ROUTE:
+ {
+ struct swarmkv_cmd *keyspace_cmd = make_keyroute_cmd(spec->flag, cmd->argv[spec->key_offset], db->opts->dryrun, &db->self);
+ struct cmd_ctx *ctx = cmd_ctx_new(db, cmd, future_of_caller);
+ ctx->future_of_mine = future_create("key_route", key_route_on_success, generic_on_fail, ctx);
+ exec_cmd(db, keyspace_cmd, ctx->future_of_mine);
+ swarmkv_cmd_free(keyspace_cmd);
+ keyspace_cmd = NULL;
+ assert(reply == NULL);
+ assert(spec->auto_route == 1);
+ break;
+ }
+ default:
+ {
+ assert(0);
+ break;
+ }
+ }
+ db->threads[cur_tid].recusion_depth--;
+}
+static struct swarmkv_reply *get_future_failed_reply(enum e_future_error err, const char *what)
{
- struct local_caller_ctx *ctx=(struct local_caller_ctx*)user;
- struct swarmkv_reply *reply=NULL;
- if(err==FUTURE_ERROR_CANCEL)
+ struct swarmkv_reply *reply = NULL;
+ if (err == FUTURE_ERROR_CANCEL)
{
- reply=swarmkv_reply_new_error("cancelled");
+ reply = swarmkv_reply_new_error("cancelled");
}
else
{
- reply=swarmkv_reply_new_error(what);
+ reply = swarmkv_reply_new_error(what);
}
+ return reply;
+}
+struct local_caller_ctx
+{
+ struct swarmkv *db;
+ swarmkv_on_reply_callback_t *cb;
+ void *cb_arg;
+ int cur_tid;
+ struct future *my_future;
+};
+static void local_caller_on_success(void *result, void *user)
+{
+ struct local_caller_ctx *ctx = (struct local_caller_ctx *)user;
+ const struct swarmkv_reply *reply = (const struct swarmkv_reply *)result;
+ int cur_tid = swarmkv_gettid(ctx->db);
+ assert(ctx->cur_tid == cur_tid);
+ ctx->cb(reply, ctx->cb_arg);
+ future_destroy(ctx->my_future);
+ free(ctx);
+}
+static void local_caller_on_fail(enum e_future_error err, const char *what, void *user)
+{
+ struct local_caller_ctx *ctx = (struct local_caller_ctx *)user;
+ struct swarmkv_reply *reply = get_future_failed_reply(err, what);
ctx->cb(reply, ctx->cb_arg);
future_destroy(ctx->my_future);
free(ctx);
swarmkv_reply_free(reply);
}
-void exec_for_local(struct swarmkv *db, const struct swarmkv_cmd *cmd, const node_t *target_node, swarmkv_on_reply_callback_t * cb, void * cb_arg)
+void exec_for_local(struct swarmkv *db, const struct swarmkv_cmd *cmd, node_t *peer, swarmkv_on_reply_callback_t *cb, void *cb_arg)
{
- struct local_caller_ctx *ctx=NULL;
- ctx=ALLOC(struct local_caller_ctx, 1);
- ctx->cb=cb;
- ctx->cb_arg=cb_arg;
- ctx->my_future=future_create("for_local",
- local_caller_on_success,
- local_caller_on_fail,
- ctx);
- __exec_cmd(db, target_node, cmd, ctx->my_future);
+ struct local_caller_ctx *ctx = NULL;
+ ctx = ALLOC(struct local_caller_ctx, 1);
+ ctx->db = db;
+ ctx->cur_tid = swarmkv_gettid(db);
+ ctx->cb = cb;
+ ctx->cb_arg = cb_arg;
+ ctx->my_future = future_create("for_local",
+ local_caller_on_success,
+ local_caller_on_fail,
+ ctx);
+ if (peer && node_compare(peer, &db->self))
+ {
+ exec_at_peer(db, cmd, peer, ctx->my_future);
+ }
+ else
+ {
+ // Call maybe from both caller thread and worker thread, i.e., in worker thread, keyspace call "crdt meet".
+ exec_cmd(db, cmd, ctx->my_future);
+ }
db->local_cmds++;
return;
}
-struct remote_caller_ctx
+struct peer_caller_ctx
{
struct future *my_future;
struct swarmkv *db;
- long long sequence;
- int remote_tid;
- node_t remote;
+ node_t peer;
+ int peer_tid;
+ long long sequence;
};
-void remote_calller_ctx_free(struct remote_caller_ctx *ctx)
+static void send_success_reply_to_peer(void *result, void *user)
{
+ struct peer_caller_ctx *ctx = (struct peer_caller_ctx *)user;
+ struct swarmkv *db = ctx->db;
+ int cur_tid = swarmkv_gettid(db);
+ const struct swarmkv_reply *reply = (const struct swarmkv_reply *)result;
+ struct swarmkv_msg *msg = swarmkv_msg_new_by_reply(reply, ctx->sequence);
+ const char *err_str = NULL;
+ swarmkv_net_send(db->net, cur_tid, &ctx->peer, ctx->peer_tid, msg, &err_str);
future_destroy(ctx->my_future);
- ctx->my_future=NULL;
- ctx->db=NULL;
free(ctx);
return;
}
-static void remoter_caller_ctx_send_reply(struct remote_caller_ctx *ctx, const struct swarmkv_reply *reply)
+static void send_failed_reply_to_peer(enum e_future_error err, const char *what, void *user)
{
+ struct peer_caller_ctx *ctx = (struct peer_caller_ctx *)user;
struct swarmkv *db = ctx->db;
- struct swarmkv_msg *msg=swarmkv_msg_new_by_reply(reply, &ctx->remote, ctx->remote_tid, &db->self, ctx->sequence);
- int cur_tid=swarmkv_gettid(db);
- const char *err_str=NULL;
- if(0==node_compare(&db->self, &msg->caller))
- {
- //Thread can not send message to itself.
- assert(cur_tid != msg->caller_tid);
- swarmkv_mesh_send(db->mesh, cur_tid, msg->caller_tid, msg);
- }
- else
- {
- swarmkv_net_send(ctx->db->net, &ctx->remote, msg, &err_str);
- }
+ int cur_tid = swarmkv_gettid(db);
+ struct swarmkv_reply *reply = get_future_failed_reply(err, what);
+ struct swarmkv_msg *msg = swarmkv_msg_new_by_reply(reply, ctx->sequence);
+ const char *err_str = NULL;
+ swarmkv_net_send(db->net, cur_tid, &ctx->peer, ctx->peer_tid, msg, &err_str);
+ swarmkv_reply_free(reply);
+ future_destroy(ctx->my_future);
+ free(ctx);
return;
}
-static void remote_caller_on_success(void *result, void *user)
+void exec_for_peer(struct swarmkv *db, const struct swarmkv_cmd *cmd, long long sequence, const node_t *peer, int peer_tid)
{
- struct remote_caller_ctx *ctx=(struct remote_caller_ctx*)user;
- const struct swarmkv_reply *reply=(const struct swarmkv_reply*) result;
- remoter_caller_ctx_send_reply(ctx, reply);
- remote_calller_ctx_free(ctx);
+ struct peer_caller_ctx *ctx = ALLOC(struct peer_caller_ctx, 1);
+ ctx->db = db;
+ ctx->sequence = sequence;
+ ctx->peer_tid = peer_tid;
+ node_copy(&ctx->peer, peer);
+ ctx->my_future = future_create("for_remote",
+ send_success_reply_to_peer,
+ send_failed_reply_to_peer,
+ ctx);
+ exec_cmd(db, cmd, ctx->my_future);
+ db->remote_cmds++;
return;
}
-static void remote_caller_on_fail(enum e_future_error err, const char * what, void * user)
+struct thread_caller_ctx
{
- struct remote_caller_ctx *ctx=(struct remote_caller_ctx*)user;
- struct swarmkv_reply *reply=NULL;
- if(err==FUTURE_ERROR_CANCEL)
- {
- reply=swarmkv_reply_new_error("cancelled");
- }
- else
- {
- reply=swarmkv_reply_new_error(what);
- remoter_caller_ctx_send_reply(ctx, reply);
- }
-
- swarmkv_reply_free(reply);
- remote_calller_ctx_free(ctx);
+ struct future *my_future;
+ struct swarmkv *db;
+ int src_tid;
+ long long sequence;
+};
+void send_success_reply_to_thread(void *result, void *user)
+{
+ struct thread_caller_ctx *ctx = (struct thread_caller_ctx *)user;
+ const struct swarmkv_reply *reply = (const struct swarmkv_reply *)result;
+ struct swarmkv *db = ctx->db;
+ struct swarmkv_msg *msg = swarmkv_msg_new_by_reply(reply, ctx->sequence);
+ int cur_tid = swarmkv_gettid(db);
+ swarmkv_mesh_send(db->mesh, cur_tid, ctx->src_tid, msg);
+ future_destroy(ctx->my_future);
+ free(ctx);
+}
+void send_failed_reply_to_thead(enum e_future_error err, const char *what, void *user)
+{
+ struct thread_caller_ctx *ctx = (struct thread_caller_ctx *)user;
+ struct swarmkv *db = ctx->db;
+ struct swarmkv_reply *reply = get_future_failed_reply(err, what);
+ int cur_tid = swarmkv_gettid(db);
+ struct swarmkv_msg *msg = swarmkv_msg_new_by_reply(reply, ctx->sequence);
+ swarmkv_mesh_send(db->mesh, cur_tid, ctx->src_tid, msg);
+ swarmkv_reply_free(reply);
+ future_destroy(ctx->my_future);
+ free(ctx);
return;
}
-void exec_for_remote(struct swarmkv *db, const struct swarmkv_msg *msg)
+void exec_for_thread(struct swarmkv *db, const struct swarmkv_cmd *cmd, long long sequence, int src_tid)
{
- struct remote_caller_ctx *ctx=ALLOC(struct remote_caller_ctx, 1);
- ctx->db=db;
- ctx->sequence=msg->sequence;
- ctx->remote_tid=msg->caller_tid;
- node_copy(&ctx->remote, &msg->caller);
- ctx->my_future=future_create("for_remote",
- remote_caller_on_success,
- remote_caller_on_fail,
- ctx);
- __exec_cmd(db, &msg->executor, msg->cmd, ctx->my_future);
- db->remote_cmds++;
- //Todo: implement monitor command here
+ struct thread_caller_ctx *ctx = NULL;
+ ctx = ALLOC(struct thread_caller_ctx, 1);
+ ctx->db = db;
+ ctx->src_tid = src_tid;
+ ctx->sequence = sequence;
+ ctx->my_future = future_create("for_thread",
+ send_success_reply_to_thread,
+ send_failed_reply_to_thead,
+ ctx);
+ exec_cmd(db, cmd, ctx->my_future);
+ db->local_cmds++;
return;
}
enum cmd_exec_result info_command(struct swarmkv_module *mod_db, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
char node_info_buff[4096], store_info_buff[4096], ks_info_buff[4096], net_info_buff[4096];
- char all_info_buff[4096*4];
- struct swarmkv *db=module2db(mod_db);
+ char all_info_buff[4096 * 4];
+ struct swarmkv *db = module2db(mod_db);
struct timespec now_monotonic;
long long server_time_us;
- server_time_us=ustime();
+ server_time_us = ustime();
clock_gettime(CLOCK_MONOTONIC, &now_monotonic);
char uuid_str[37];
uuid_unparse(db->opts->bin_uuid, uuid_str);
- sds pending_cmds=sdsnew("[");
- size_t rpc_cnt=0;
- for(int i=0; i<db->opts->total_threads; i++)
+ sds pending_cmds = sdsnew("[");
+ size_t rpc_cnt = 0;
+ for (int i = 0; i < db->opts->total_threads; i++)
{
- rpc_cnt=swarmkv_rpc_mgr_count(db->rpc_mgr, i);
- pending_cmds=sdscatprintf(pending_cmds, "%zu", rpc_cnt);
- if(i==db->opts->nr_worker_threads-1)
+ rpc_cnt = swarmkv_rpc_mgr_count(db->rpc_mgr, i);
+ pending_cmds = sdscatprintf(pending_cmds, "%zu", rpc_cnt);
+ if (i == db->opts->nr_worker_threads - 1)
{
- pending_cmds=sdscatprintf(pending_cmds, "], [");
+ pending_cmds = sdscatprintf(pending_cmds, "], [");
}
- else if(i==db->opts->total_threads-1)
+ else if (i == db->opts->total_threads - 1)
{
- pending_cmds=sdscatprintf(pending_cmds, "]");
+ pending_cmds = sdscatprintf(pending_cmds, "]");
}
else
{
- pending_cmds=sdscatprintf(pending_cmds, ", ");
+ pending_cmds = sdscatprintf(pending_cmds, ", ");
}
}
struct swarmkv_rpc_mgr_info rpc_info;
@@ -279,272 +672,241 @@ enum cmd_exec_result info_command(struct swarmkv_module *mod_db, const struct sw
struct mesh_info mesh_info;
swarmkv_mesh_info(db->mesh, &mesh_info);
snprintf(node_info_buff, sizeof(node_info_buff), "# Node\r\n"
- "version: %s\r\n"
- "address: %s\r\n"
- "uuid: %s\r\n"
- "worker_threads: %d\r\n"
- "caller_threads: %d\r\n"
- "pending_cmds: %s\r\n"
- "local_cmds: %lld\r\n"
- "remote_cmds: %lld\r\n"
- "timed_out_cmds: %lld\r\n"
- "unknown_sequence: %lld\r\n"
- "mesh_queued_msgs: %lld\r\n"
- "mesh_drop_msgs: %lld\r\n"
- "server_time_usec: %lld\r\n"
- "up_time_in_seconds: %ld\r\n"
- "up_time_in_days: %ld\r\n"
- ,
- GIT_VERSION,
- db->self.addr,
- uuid_str,
- db->opts->nr_worker_threads,
- db->opts->nr_caller_threads,
- pending_cmds,
- db->local_cmds,
- db->remote_cmds,
- rpc_info.timed_out_rpcs,
- rpc_info.unknown_sequence,
- mesh_info.queued_msgs,
- mesh_info.enqueue_drops,
- server_time_us,
- now_monotonic.tv_sec-db->boot_time.tv_sec,
- (now_monotonic.tv_sec-db->boot_time.tv_sec)/(3600*24)
- );
+ "version: %s\r\n"
+ "address: %s\r\n"
+ "uuid: %s\r\n"
+ "worker_threads: %d\r\n"
+ "caller_threads: %d\r\n"
+ "pending_cmds: %s\r\n"
+ "local_cmds: %lld\r\n"
+ "remote_cmds: %lld\r\n"
+ "timed_out_cmds: %lld\r\n"
+ "unknown_sequence: %lld\r\n"
+ "mesh_queued_msgs: %lld\r\n"
+ "mesh_drop_msgs: %lld\r\n"
+ "server_time_usec: %lld\r\n"
+ "up_time_in_seconds: %ld\r\n"
+ "up_time_in_days: %ld\r\n",
+ GIT_VERSION,
+ db->self.addr,
+ uuid_str,
+ db->opts->nr_worker_threads,
+ db->opts->nr_caller_threads,
+ pending_cmds,
+ db->local_cmds,
+ db->remote_cmds,
+ rpc_info.timed_out_rpcs,
+ rpc_info.unknown_sequence,
+ mesh_info.queued_msgs,
+ mesh_info.enqueue_drops,
+ server_time_us,
+ now_monotonic.tv_sec - db->boot_time.tv_sec,
+ (now_monotonic.tv_sec - db->boot_time.tv_sec) / (3600 * 24));
sdsfree(pending_cmds);
struct store_info sto_info;
swarmkv_store_info(db->mod_store, &sto_info);
snprintf(store_info_buff, sizeof(store_info_buff), "# Store\r\n"
- "keys: %lld\r\n"
- "to_sync: %lld\r\n"
- "synced: %lld\r\n"
- "sync_ok: %lld\r\n"
- "sync_err: %lld\r\n"
- "sync_interval_in_msec: %.3f\r\n"
- ,
- sto_info.keys,
- sto_info.keys_to_sync,
- sto_info.synced,
- sto_info.sync_ok,
- sto_info.sync_err,
- (double)db->opts->sync_interval_us/1000
- );
+ "keys: %lld\r\n"
+ "to_sync: %lld\r\n"
+ "synced: %lld\r\n"
+ "sync_ok: %lld\r\n"
+ "sync_err: %lld\r\n"
+ "sync_interval_in_msec: %.3f\r\n",
+ sto_info.keys,
+ sto_info.keys_to_sync,
+ sto_info.synced,
+ sto_info.sync_ok,
+ sto_info.sync_err,
+ (double)db->opts->sync_interval_us / 1000);
struct keyspace_info ks_info;
swarmkv_keyspace_info(db->mod_keyspace, &ks_info);
snprintf(ks_info_buff, sizeof(ks_info_buff), "# Keyspace\r\n"
- "health_check_port: %u\r\n"
- "slots: %lld\r\n"
- "keys: %lld\r\n"
- "expires: %lld\r\n"
- ,
- ks_info.health_check_port,
- ks_info.slots,
- ks_info.keys,
- ks_info.expires);
+ "health_check_port: %u\r\n"
+ "slots: %lld\r\n"
+ "keys: %lld\r\n"
+ "expires: %lld\r\n",
+ ks_info.health_check_port,
+ ks_info.slots,
+ ks_info.keys,
+ ks_info.expires);
struct snet_info net_info;
swarmkv_net_info(db->net, &net_info);
snprintf(net_info_buff, sizeof(net_info_buff), "# Network\r\n"
- "timeout_in_msec: %.3f\r\n"
- "output_buf_max: %lld\r\n"
- "connections: %lld\r\n"
- "input_bytes: %lld\r\n"
- "output_bytes: %lld\r\n"
- "input_msgs: %lld\r\n"
- "output_msgs: %lld\r\n"
- "input_error_msgs: %lld\r\n"
- "output_drop_msgs: %lld\r\n"
- "input_buffer: %lld\r\n"
- "output_buffer: %lld\r\n"
- "instantaneous_input_kbps: %.2f\r\n"
- "instantaneous_output_kbps: %.2f\r\n"
- "instantaneous_input_msgs: %.2f\r\n"
- "instantaneous_output_msgs: %.2f\r\n"
- ,
- (double)db->opts->cluster_timeout_us/1000,
- net_info.output_buf_max,
- net_info.connections,
- net_info.input_bytes,
- net_info.output_bytes,
- net_info.input_msgs,
- net_info.output_msgs,
- net_info.input_error_msgs,
- net_info.output_drop_msgs,
- net_info.input_buffer_sz,
- net_info.output_buffer_sz,
- net_info.instantaneous_input_kbps,
- net_info.instantaneous_output_kbps,
- net_info.instantaneous_input_msgs,
- net_info.instantaneous_output_msgs
- );
-
- if(cmd->argc>1)
+ "timeout_in_msec: %.3f\r\n"
+ "output_buf_max: %lld\r\n"
+ "connections: %lld\r\n"
+ "input_bytes: %lld\r\n"
+ "output_bytes: %lld\r\n"
+ "input_msgs: %lld\r\n"
+ "output_msgs: %lld\r\n"
+ "input_error_msgs: %lld\r\n"
+ "output_drop_msgs: %lld\r\n"
+ "input_buffer: %lld\r\n"
+ "output_buffer: %lld\r\n"
+ "instantaneous_input_kbps: %.2f\r\n"
+ "instantaneous_output_kbps: %.2f\r\n"
+ "instantaneous_input_msgs: %.2f\r\n"
+ "instantaneous_output_msgs: %.2f\r\n"
+ "compression: %s\r\n"
+ "input_compression_ratio: %.2f\r\n"
+ "output_compression_ratio: %.2f\r\n",
+ (double)db->opts->cluster_timeout_us / 1000,
+ net_info.output_buf_max,
+ net_info.connections,
+ net_info.input_bytes,
+ net_info.output_bytes,
+ net_info.input_msgs,
+ net_info.output_msgs,
+ net_info.input_error_msgs,
+ net_info.output_drop_msgs,
+ net_info.input_buffer_sz,
+ net_info.output_buffer_sz,
+ net_info.instantaneous_input_kbps,
+ net_info.instantaneous_output_kbps,
+ net_info.instantaneous_input_msgs,
+ net_info.instantaneous_output_msgs,
+ db->opts->network_compression_enabled ? "snappy" : "off",
+ net_info.input_compression_ratio,
+ net_info.output_compression_ratio);
+
+ if (cmd->argc > 1)
{
- if(0==strcasecmp("Node", cmd->argv[1]))
+ if (0 == strcasecmp("Node", cmd->argv[1]))
{
- *reply=swarmkv_reply_new_status(node_info_buff);
+ *reply = swarmkv_reply_new_status(node_info_buff);
}
- else if(0==strcasecmp("Store", cmd->argv[1]))
+ else if (0 == strcasecmp("Store", cmd->argv[1]))
{
- *reply=swarmkv_reply_new_status(store_info_buff);
+ *reply = swarmkv_reply_new_status(store_info_buff);
}
- else if(0==strcasecmp("Keyspace", cmd->argv[1]))
+ else if (0 == strcasecmp("Keyspace", cmd->argv[1]))
{
- *reply=swarmkv_reply_new_status(ks_info_buff);
+ *reply = swarmkv_reply_new_status(ks_info_buff);
}
- else if(0==strcasecmp("Network", cmd->argv[1]))
+ else if (0 == strcasecmp("Network", cmd->argv[1]))
{
- *reply=swarmkv_reply_new_status(net_info_buff);
+ *reply = swarmkv_reply_new_status(net_info_buff);
}
- else if(0==strcasecmp("Threads", cmd->argv[1]))
+ else if (0 == strcasecmp("Threads", cmd->argv[1]))
{
- *reply=swarmkv_reply_new_string_from_integer(db->opts->nr_worker_threads);
+ *reply = swarmkv_reply_new_string_from_integer(db->opts->nr_worker_threads);
}
else
{
- *reply=swarmkv_reply_new_verbatim("", 1, "txt");
+ *reply = swarmkv_reply_new_verbatim("", 1, "txt");
}
}
else
{
snprintf(all_info_buff, sizeof(all_info_buff), "%s\n%s\n%s\n%s",
- node_info_buff,
- store_info_buff,
- ks_info_buff,
- net_info_buff);
- *reply=swarmkv_reply_new_status(all_info_buff);
+ node_info_buff,
+ store_info_buff,
+ ks_info_buff,
+ net_info_buff);
+ *reply = swarmkv_reply_new_status(all_info_buff);
}
return FINISHED;
}
enum cmd_exec_result ping_command(struct swarmkv_module *mod_db, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- struct swarmkv *db=module2db(mod_db);
+ struct swarmkv *db = module2db(mod_db);
node_t target;
node_init_from_sds(&target, cmd->argv[1]);
- if(0==node_compare(&target, &db->self))
+ if (0 == node_compare(&target, &db->self))
{
- *reply=swarmkv_reply_new_string_fmt("PONG from %s", swarmkv_self_address(db));
+ *reply = swarmkv_reply_new_string_fmt("PONG from %s", swarmkv_self_address(db));
return FINISHED;
}
else
{
- *reply=swarmkv_reply_new_node(&target, 1);
+ *reply = swarmkv_reply_new_node(&target, 1);
return REDIRECT;
}
}
enum cmd_exec_result __attribute__((optimize("O0"))) debug_command(struct swarmkv_module *mod_db, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- if(cmd->argc==2 && !strcasecmp(cmd->argv[1], "help") )
+ if (cmd->argc == 2 && !strcasecmp(cmd->argv[1], "help"))
{
const char *help = {
-"DEBUG <subcommand> [<arg> [value] [opt] ...]. Subcommands are:\n"
-"SLEEP <seconds>\n"
-" Stop the server for <seconds>. Decimals allowed.\n"
-"ASSERT\n"
-" Crash by assertion failed.\n"
- };
- *reply=swarmkv_reply_new_status(help);
+ "DEBUG <subcommand> [<arg> [value] [opt] ...]. Subcommands are:\n"
+ "SLEEP <seconds>\n"
+ " Stop the server for <seconds>. Decimals allowed.\n"
+ "ASSERT\n"
+ " Crash by assertion failed.\n"};
+ *reply = swarmkv_reply_new_status(help);
}
- else if(!strcasecmp(cmd->argv[1], "sleep") && cmd->argc>2)
+ else if (!strcasecmp(cmd->argv[1], "sleep") && cmd->argc > 2)
{
- if(cmd->argc<3)
+ if (cmd->argc < 3)
{
- *reply=swarmkv_reply_new_error(error_need_additional_arg, cmd->argv[1]);
+ *reply = swarmkv_reply_new_error(error_need_additional_arg, cmd->argv[1]);
}
else
{
double dtime = strtod(cmd->argv[2], NULL);
- long long utime = dtime*1000000;
+ long long utime = dtime * 1000000;
struct timespec tv;
tv.tv_sec = utime / 1000000;
tv.tv_nsec = (utime % 1000000) * 1000;
nanosleep(&tv, NULL);
- *reply=swarmkv_reply_new_status("OK");
- }
+ *reply = swarmkv_reply_new_status("OK");
+ }
}
- else if(!strcasecmp(cmd->argv[1], "assert"))
+ else if (!strcasecmp(cmd->argv[1], "assert"))
{
assert(0);
}
else
{
- *reply=swarmkv_reply_new_error(erorr_subcommand_syntax, cmd->argv[1], cmd->argv[0]);
+ *reply = swarmkv_reply_new_error(erorr_subcommand_syntax, cmd->argv[1], cmd->argv[0]);
}
return FINISHED;
}
enum cmd_exec_result print_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
printf("%s", cmd->argv[1]);
- *reply=swarmkv_reply_new_status("OK");
+ *reply = swarmkv_reply_new_status("OK");
return FINISHED;
}
enum cmd_exec_result config_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- //Unused
+ // Unused
return FINISHED;
}
-enum cmd_exec_result command_list_command(struct swarmkv_module *mod_db, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
-{
- struct swarmkv *db=module2db(mod_db);
- size_t cnt=HASH_COUNT(db->command_table);
- struct swarmkv_cmd_spec *spec=NULL, *tmp_spec=NULL;
- int i=0;
- *reply=swarmkv_reply_new_array(cnt);
- HASH_ITER(hh, db->command_table, spec, tmp_spec)
- {
- (*reply)->elements[i]=swarmkv_reply_new_string(spec->name, strlen(spec->name));
- i++;
- }
- assert(i==cnt);
- return FINISHED;
-}
-struct swarmkv_cmd_spec *get_spec_by_argv(struct swarmkv *db, size_t argc, char* const argv[])
+
+__attribute__((unused)) static void libevent_log_cb(int severity, const char *msg)
{
- struct swarmkv_cmd_spec *spec=NULL;
- char name[256]="";
- strncpy(name, argv[0], sizeof(name));
- toUpper(name);
- HASH_FIND(hh, db->command_table, name, strlen(name), spec);
- if(spec)
- {
- return spec;
- }
- if(argc<2)
- {
- return NULL;
- }
- snprintf(name, sizeof(name), "%s %s", argv[0], argv[1]);
- toUpper(name);
- HASH_FIND(hh, db->command_table, name, strlen(name), spec);
- if(spec)
+ const char *s;
+ FILE *logfile = fopen("libevent_run.log", "a");
+ switch (severity)
{
- return spec;
+ case _EVENT_LOG_DEBUG:
+ s = "debug";
+ break;
+ case _EVENT_LOG_MSG:
+ s = "msg";
+ break;
+ case _EVENT_LOG_WARN:
+ s = "warn";
+ break;
+ case _EVENT_LOG_ERR:
+ s = "error";
+ break;
+ default:
+ s = "?";
+ break; // never reached
}
- return NULL;
-}
-
-
- __attribute__((unused)) static void libevent_log_cb(int severity, const char *msg)
-{
- const char *s;
- FILE *logfile=fopen("libevent_run.log", "a");
- switch (severity) {
- case _EVENT_LOG_DEBUG: s = "debug"; break;
- case _EVENT_LOG_MSG: s = "msg"; break;
- case _EVENT_LOG_WARN: s = "warn"; break;
- case _EVENT_LOG_ERR: s = "error"; break;
- default: s = "?"; break; // never reached
- }
- fprintf(logfile, "[%s] %s\n", s, msg);
+ fprintf(logfile, "[%s] %s\n", s, msg);
fclose(logfile);
sleep(1000);
}
-void __swarmkv_periodic(evutil_socket_t fd, short what, void * arg)
+void __swarmkv_periodic(evutil_socket_t fd, short what, void *arg)
{
- struct swarmkv_thread *thr=(struct swarmkv_thread *)arg;
-
+ struct swarmkv_thread *thr = (struct swarmkv_thread *)arg;
+
swarmkv_store_periodic(thr->db->mod_store, thr->thread_id);
swarmkv_keyspace_periodic(thr->db->mod_keyspace, thr->thread_id);
}
@@ -552,43 +914,42 @@ void *swarmkv_worker_thread(void *arg)
{
struct swarmkv *db = (struct swarmkv *)arg;
swarmkv_register_thread(db);
- int tid=swarmkv_gettid(db);
- struct swarmkv_thread *thr = db->threads+tid;
+ int tid = swarmkv_gettid(db);
+ struct swarmkv_thread *thr = db->threads + tid;
char thread_name[16];
snprintf(thread_name, sizeof(thread_name), "swarmkv-%u", thr->thread_id);
- prctl(PR_SET_NAME, (unsigned long long) thread_name, NULL, NULL, NULL);
+ prctl(PR_SET_NAME, (unsigned long long)thread_name, NULL, NULL, NULL);
- struct timeval sync_interval = {db->opts->sync_interval_us/(1000*1000), db->opts->sync_interval_us%(1000*1000)};
- struct event * periodic_ev=event_new(thr->evbase, -1, EV_PERSIST, __swarmkv_periodic, thr);
+ struct timeval sync_interval = {db->opts->sync_interval_us / (1000 * 1000), db->opts->sync_interval_us % (1000 * 1000)};
+ struct event *periodic_ev = event_new(thr->evbase, -1, EV_PERSIST, __swarmkv_periodic, thr);
evtimer_add(periodic_ev, &sync_interval);
-
- thr->is_dispatching=1;
+
+ thr->is_dispatching = 1;
pthread_barrier_wait(&db->barrier);
-
- int ret=event_base_dispatch(thr->evbase);
+ int ret = event_base_dispatch(thr->evbase);
event_del(periodic_ev);
event_free(periodic_ev);
- if(thr->is_dispatching)
+ if (thr->is_dispatching)
{
log_fatal(db->logger, MODULE_SWAMRKV_CORE, "worker thread event_base_dispatch() exit abnormally, ret=%d", ret);
}
else
{
log_info(thr->db->logger, MODULE_SWAMRKV_CORE, "%s worker thread %d exited", thr->db->db_name, thr->sys_tid);
- }
+ }
return NULL;
}
void swarmkv_threads_run(struct swarmkv *db)
{
- pthread_barrier_init(&db->barrier, NULL, db->opts->nr_worker_threads+1);
- int i = 0, ret=0;
+ pthread_barrier_init(&db->barrier, NULL, db->opts->nr_worker_threads + 1);
+ int i = 0, ret = 0;
for (i = 0; i < db->opts->nr_worker_threads; i++)
{
- ret=pthread_create(&db->threads[i].thr, NULL, swarmkv_worker_thread, db);
- if(ret !=0 )//error
+ ret = pthread_create(&db->threads[i].thr, NULL, swarmkv_worker_thread, db);
+ if (ret != 0) // error
{
log_fatal(db->logger, MODULE_SWAMRKV_CORE, "pthread_create() error %d", ret);
}
@@ -597,822 +958,331 @@ void swarmkv_threads_run(struct swarmkv *db)
return;
}
-static struct swarmkv_reply *key_not_found_reply(enum key_not_found_reply not_found_flag)
-{
- struct swarmkv_reply *reply=NULL;
- switch(not_found_flag)
- {
- case REPLY_INT_0:
- reply=swarmkv_reply_new_integer(0);
- break;
- case REPLY_INT_MINORS1:
- reply=swarmkv_reply_new_integer(-1);
- break;
- case REPLY_NIL:
- reply=swarmkv_reply_new_nil();
- break;
- case REPLY_EMPTY_ARRAY:
- reply=swarmkv_reply_new_array(0);
- break;
- case REPLY_STR_NONE:
- reply=swarmkv_reply_new_string_fmt("none");
- break;
- case REPLY_ERROR:
- reply=swarmkv_reply_new_error(error_keyspace_obj_owner_not_found);
- break;
- default:
- assert(0);
- break;
- }
- return reply;
-}
-
-static struct swarmkv_cmd *make_keyroute_cmd(enum cmd_key_flag flag, const sds key, int dry_run, const node_t *caller)
-{
- struct swarmkv_cmd *keyroute_cmd=NULL;
- switch(flag)
- {
- case CMD_KEY_RO:
- case CMD_KEY_RW:
- if(!dry_run)
- {
- keyroute_cmd=swarmkv_cmd_new(4, caller);
- keyroute_cmd->argv[0]=sdsnew("keyspace");
- keyroute_cmd->argv[1]=sdsnew("xradd");
- keyroute_cmd->argv[2]=sdsdup(key);
- keyroute_cmd->argv[3]=node_addr2sds(caller);
- }
- else
- {
- keyroute_cmd=swarmkv_cmd_new(3, caller);
- keyroute_cmd->argv[0]=sdsnew("keyspace");
- keyroute_cmd->argv[1]=sdsnew("rlist");
- keyroute_cmd->argv[2]=sdsdup(key);
- }
- break;
- case CMD_KEY_OW:
- if(!dry_run)
- {
- keyroute_cmd=swarmkv_cmd_new(4, caller);
- keyroute_cmd->argv[0]=sdsnew("keyspace");
- keyroute_cmd->argv[1]=sdsnew("radd");
- keyroute_cmd->argv[2]=sdsdup(key);
- keyroute_cmd->argv[3]=node_addr2sds(caller);
- }
- else
- {
- keyroute_cmd=swarmkv_cmd_new(3, caller);
- keyroute_cmd->argv[0]=sdsnew("keyspace");
- keyroute_cmd->argv[1]=sdsnew("radd");
- keyroute_cmd->argv[2]=sdsdup(key);
- }
- break;
- case CMD_KEY_RM:
- assert(0);
- keyroute_cmd=swarmkv_cmd_new(3, caller);
- keyroute_cmd->argv[0]=sdsnew("keyspace");
- keyroute_cmd->argv[1]=sdsnew("del");
- keyroute_cmd->argv[2]=sdsdup(key);
- break;
- default:
- assert(0);
- break;
- }
- return keyroute_cmd;
-}
-int is_sufficient_arg_num(const struct swarmkv_cmd_spec *spec, const struct swarmkv_cmd *cmd)
-{
- size_t expect_argc=0;
- if(strchr(spec->name, ' '))
- {
- expect_argc=spec->arity+2;
- }
- else
- {
- expect_argc=spec->arity+1;
- }
- if(cmd->argc<expect_argc)
- {
- return 0;
- }
- return 1;
-}
-struct cmd_ctx
-{
- struct swarmkv *db;
- struct swarmkv_cmd *cmd;
- int redirect_cnt;
- struct future *future_of_mine;
- struct future *future_of_caller;
-};
-
-struct cmd_ctx *cmd_ctx_new(struct swarmkv *db, const struct swarmkv_cmd *cmd, struct future *f)
-{
- struct cmd_ctx *ctx=ALLOC(struct cmd_ctx, 1);
- ctx->db=db;
- ctx->cmd=swarmkv_cmd_dup(cmd);
- ctx->redirect_cnt=0;
- ctx->future_of_caller=f;
- return ctx;
-}
-void cmd_ctx_free(struct cmd_ctx *ctx)
-{
- swarmkv_cmd_free(ctx->cmd);
- future_destroy(ctx->future_of_mine);
- free(ctx);
- return;
-}
-static void generic_on_fail(enum e_future_error err, const char * what, void * user)
-{
- struct cmd_ctx *ctx=(struct cmd_ctx*)user;
- if(ctx->future_of_caller)
- {
- struct promise *p=future_to_promise(ctx->future_of_caller);
- promise_failed(p, err, what);
- }
- cmd_ctx_free(ctx);
-}
-static void peer_exec_on_success(void *result, void *user)
-{
- struct cmd_ctx *ctx = (struct cmd_ctx*)user;
- struct swarmkv_reply *reply = (struct swarmkv_reply*) result;
-
- if(reply->type==SWARMKV_REPLY_NODE && 0==strncasecmp(reply->str, "-ASK", 4))
- {
- ctx->redirect_cnt++;
- if(ctx->redirect_cnt<=3)
- {
- node_t target_node;
- node_init_from_reply(&target_node, reply);
- __exec_cmd(ctx->db, &target_node, ctx->cmd, ctx->future_of_mine);
- }
- else
- {
- char err_msg[256];
- snprintf(err_msg, sizeof(err_msg), error_too_many_redirects, reply->str);
- struct promise *p=future_to_promise(ctx->future_of_caller);
- promise_failed(p, FUTURE_ERROR_EXCEPTION, err_msg);
- cmd_ctx_free(ctx);
- }
- }
- else
- {
- struct promise *p=future_to_promise(ctx->future_of_caller);
- promise_success(p, (void*) reply);
- cmd_ctx_free(ctx);
- }
-}
-struct swarmkv_cmd *make_crdt_add_cmd(const sds key, node_t replica[], size_t n_replica, const node_t *caller)
-{
- struct swarmkv_cmd *crdt_add_cmd=NULL;
- crdt_add_cmd=swarmkv_cmd_new(3+n_replica, caller);
- crdt_add_cmd->argv[0]=sdsnew("crdt");
- crdt_add_cmd->argv[1]=sdsnew("add");
- crdt_add_cmd->argv[2]=sdsdup(key);
- for(size_t i=0; i<n_replica; i++)
- {
- crdt_add_cmd->argv[3+i]=node_addr2sds(replica+i);
- }
- return crdt_add_cmd;
-}
-static void crdt_add_on_success(void *result, void *user)
-{
- struct swarmkv_reply *reply=(struct swarmkv_reply*)result;
- struct cmd_ctx *ctx = (struct cmd_ctx*)user;
- assert(reply->type==SWARMKV_REPLY_STATUS);
- if(ctx->future_of_caller)
- {
- __exec_cmd(ctx->db, NULL, ctx->cmd, ctx->future_of_caller);
- }
- cmd_ctx_free(ctx);
-}
-static void key_route_on_success(void *result, void *user)
+#define MONITOR_INTER_THREAD_RPC "inter-thread-rpc"
+void __on_mesh_msg_callback(struct swarmkv_msg *msg, int src_tid, void *arg)
{
- struct cmd_ctx *ctx = (struct cmd_ctx*)user;
- const struct swarmkv_reply *reply = (const struct swarmkv_reply*) result;
- struct swarmkv_reply *user_reply_for_keyspace_not_found=NULL;
- size_t n_replica_node=0;
- node_t *replica_nodes=NULL;
- struct swarmkv_cmd_spec *spec=get_spec_by_argv(ctx->db, ctx->cmd->argc, ctx->cmd->argv);
-
- node_list_new_from_reply(&replica_nodes, &n_replica_node, reply);
- if(n_replica_node==0)
+ struct swarmkv *db = (struct swarmkv *)arg;
+ int cur_tid = swarmkv_gettid(db);
+ if (msg->type == SWARMKV_MSG_TYPE_CMD)
{
- user_reply_for_keyspace_not_found=key_not_found_reply(spec->nokey_reply);
- struct promise *p=future_to_promise(ctx->future_of_caller);
- promise_success(p, user_reply_for_keyspace_not_found);
- swarmkv_reply_free(user_reply_for_keyspace_not_found);
- user_reply_for_keyspace_not_found=NULL;
+ // command is from other thread
+ exec_for_thread(db, msg->cmd, msg->sequence, src_tid);
+ swarmkv_msg_free(msg);
}
else
{
- const sds key=ctx->cmd->argv[spec->key_offset];
- int self_is_a_replica=node_list_exists(replica_nodes, n_replica_node, &ctx->db->self);
- if(self_is_a_replica)
- {
- n_replica_node-=node_list_remove(replica_nodes, n_replica_node, &ctx->db->self);
- }
- if(n_replica_node>0)
+ long long latency_us = -1;
+ latency_us = swarmkv_rpc_complete(db->rpc_mgr, cur_tid, msg->sequence, msg->reply);
+ if (latency_us >= 0)
{
- __exec_cmd(ctx->db, replica_nodes+0, ctx->cmd, ctx->future_of_caller);
- }
- if(self_is_a_replica)
- {
- struct cmd_ctx *crdt_add_ctx=NULL;
- struct swarmkv_cmd *crdt_add_cmd=make_crdt_add_cmd(key, replica_nodes, n_replica_node, &ctx->db->self);
- crdt_add_ctx=cmd_ctx_new(ctx->db, ctx->cmd, n_replica_node>0?NULL:ctx->future_of_caller);
- crdt_add_ctx->future_of_mine=future_create("crdt_add", crdt_add_on_success, generic_on_fail, crdt_add_ctx);
- __exec_cmd(ctx->db, &ctx->db->self, crdt_add_cmd, crdt_add_ctx->future_of_mine);
- swarmkv_cmd_free(crdt_add_cmd);
+ swarmkv_monitor_record_event(db->mod_monitor, MONITOR_INTER_THREAD_RPC, latency_us);
}
- free(replica_nodes);
- }
- cmd_ctx_free(ctx);
-}
-
-static int spec_gettid(struct swarmkv_cmd_spec *spec, const struct swarmkv_cmd *cmd, int nr_worker_threads)
-{
- int tid=0;
- switch(spec->key_offset)
- {
- case KEY_OFFSET_TID:
- tid=atoi(cmd->argv[2]);
- break;
- case KEY_OFFSET_SLOTID:
- tid=swarmkv_keyspace_slot2tid(spec->module, atoi(cmd->argv[2]));
- break;
- default:
- tid=key2tid(cmd->argv[spec->key_offset], nr_worker_threads);
- break;
+ swarmkv_msg_free(msg);
}
- return tid;
}
-#define MONITOR_INTER_THREAD_RPC "inter-thread-rpc"
-void __on_msg_callback(struct swarmkv_msg *msg, void *arg)
+void __on_net_msg_callback(struct swarmkv_msg *msg, const node_t *peer, int peer_tid, void *arg)
{
struct swarmkv *db = (struct swarmkv *)arg;
- int cur_tid=swarmkv_gettid(db);
- if(msg->type==MSG_TYPE_CMD)
+ int cur_tid = swarmkv_gettid(db);
+ if (msg->type == SWARMKV_MSG_TYPE_CMD)
{
- //command may be from other thread or other node.
- assert(cur_tid < db->opts->nr_worker_threads);
- exec_for_remote(db, msg);
+ // command is from other node
+ exec_for_peer(db, msg->cmd, msg->sequence, peer, peer_tid);
swarmkv_msg_free(msg);
}
- else//MSG_TYPE_REPLY
- {
- if(msg->caller_tid!=cur_tid)
- {
- //The msg's onwership is transfered to swarmkv_mesh_send.
- swarmkv_mesh_send(db->mesh, cur_tid, msg->caller_tid, msg);
- }
- else
- {
- long long latency_us=-1;
- latency_us=swarmkv_rpc_complete(db->rpc_mgr, cur_tid, msg->sequence, msg->reply);
- if(latency_us>=0)
- {
- if(node_compare(&db->self, &msg->executor))
- {
- swarmkv_monitor_record_peer(db->mod_monitor, &msg->executor, latency_us, cur_tid);
- }
- else
- {
- swarmkv_monitor_record_event(db->mod_monitor, MONITOR_INTER_THREAD_RPC, latency_us);
- }
- }
- swarmkv_msg_free(msg);
- }
- }
-}
-#define INTER_THREAD_RPC_TIMEOUT_AHEAD 1000
-void __exec_cmd(struct swarmkv *db, const node_t *target_node, const struct swarmkv_cmd *cmd, struct future *future_of_caller)
-{
- struct swarmkv_cmd_spec *spec=NULL;
- struct swarmkv_reply *reply=NULL;
- struct promise *p=NULL;
- int cur_tid=swarmkv_gettid(db);
-
- spec=get_spec_by_argv(db, cmd->argc, cmd->argv);
- if(!spec)
- {
- reply=swarmkv_reply_new_error(error_unknown_command, cmd->argv[0], cmd->argc>1?cmd->argv[1]:" ");
- p=future_to_promise(future_of_caller);
- promise_success(p, reply);
- swarmkv_reply_free(reply);
- return;
- }
- if(!is_sufficient_arg_num(spec, cmd))//error happens
- {
- reply=swarmkv_reply_new_error(error_wrong_number_of_arg, spec->name);
- p=future_to_promise(future_of_caller);
- promise_success(p, reply);
- swarmkv_reply_free(reply);
- return;
- }
-
- int target_tid=spec_gettid(spec, cmd, db->opts->nr_worker_threads);
-
- struct swarmkv_msg *msg=NULL;
- if(!node_is_empty(target_node) && node_compare(&db->self, target_node))
- {
- //cmd is executed in target node's on_msg_callback
- struct swarmkv_rpc *rpc=swarmkv_rpc_launch(db->rpc_mgr, cur_tid, future_of_caller);
- long long sequence=swarmkv_rpc_get_sequence(rpc);
- msg=swarmkv_msg_new_by_cmd(cmd, &db->self, cur_tid, target_node, sequence);
- int ret=0;
- if(cur_tid >= db->opts->nr_worker_threads)
- {
- //Only worker threads can do network communication, so command should be executed at worker thread first.
- ret=swarmkv_mesh_send(db->mesh, cur_tid, random()%db->opts->nr_worker_threads, msg);
- if(ret<0)
- {
- reply=swarmkv_reply_new_error(error_thread_rpc_buffer_full);
- }
- swarmkv_rpc_set_timeout(rpc, db->opts->cluster_timeout_us+INTER_THREAD_RPC_TIMEOUT_AHEAD);
- }
- else
- {
- const char *err_str=NULL;
- ret=swarmkv_net_send(db->net, target_node, msg, &err_str);
- if(ret<0)
- {
- sds target_node_peer=node_addr2sds(target_node);
- reply=swarmkv_reply_new_error(error_network_error, target_node_peer, err_str);
- sdsfree(target_node_peer);
- }
- swarmkv_rpc_set_peer(rpc, target_node);
- }
- if(reply)
- {
- swarmkv_rpc_complete(db->rpc_mgr, cur_tid, cur_tid, reply);
- swarmkv_reply_free(reply);
- }
- return;
- }
- if(cur_tid != target_tid)
- {
- //cmd will be executed in target thread's on_msg_callback
- struct swarmkv_rpc *rpc=swarmkv_rpc_launch(db->rpc_mgr, cur_tid, future_of_caller);
- swarmkv_rpc_set_timeout(rpc, db->opts->cluster_timeout_us+INTER_THREAD_RPC_TIMEOUT_AHEAD);
- long long sequence=swarmkv_rpc_get_sequence(rpc);
- msg=swarmkv_msg_new_by_cmd(cmd, &db->self, cur_tid, target_node, sequence);
- int ret=0;
- ret=swarmkv_mesh_send(db->mesh, cur_tid, target_tid, msg);
- if(ret<0)
- {
- reply=swarmkv_reply_new_error(error_thread_rpc_buffer_full);
- swarmkv_rpc_complete(db->rpc_mgr, cur_tid, cur_tid, reply);
- swarmkv_reply_free(reply);
- }
- return;
- }
- db->threads[cur_tid].recusion_depth++;
- assert(db->threads[cur_tid].recusion_depth<8);
- enum cmd_exec_result exec_ret=FINISHED;
- struct timespec start, end;
- clock_gettime(CLOCK_MONOTONIC_COARSE, &start);
- exec_ret=spec->proc(spec->module, cmd, &reply);
- clock_gettime(CLOCK_MONOTONIC_COARSE, &end);
- swarmkv_monitor_record_command(db->mod_monitor, spec, cmd, timespec_diff_usec(&start, &end), exec_ret);
-
- switch(exec_ret)
+ else
{
- case FINISHED:
- {
- struct promise *p=future_to_promise(future_of_caller);
- promise_success(p, reply);
- swarmkv_reply_free(reply);
- break;
- }
- case REDIRECT:
- {
- node_t peer;
- struct cmd_ctx *ctx=cmd_ctx_new(db, cmd, future_of_caller);
- node_init_from_reply(&peer, reply);
- swarmkv_reply_free(reply);
- //Should never redirect to myself
- assert(node_compare(&peer, &db->self));
- ctx->future_of_mine=future_create("peer_exec", peer_exec_on_success, generic_on_fail, ctx);
- __exec_cmd(db, &peer, cmd, ctx->future_of_mine);
- break;
- }
- case NEED_KEY_ROUTE:
+ long long latency_us = -1;
+ latency_us = swarmkv_rpc_complete(db->rpc_mgr, cur_tid, msg->sequence, msg->reply);
+ if (latency_us >= 0)
{
- struct swarmkv_cmd *keyspace_cmd=make_keyroute_cmd(spec->flag, cmd->argv[spec->key_offset], db->opts->dryrun, &db->self);
- struct cmd_ctx *ctx=cmd_ctx_new(db, cmd, future_of_caller);
- ctx->future_of_mine=future_create("key_route", key_route_on_success, generic_on_fail, ctx);
- __exec_cmd(db, NULL, keyspace_cmd, ctx->future_of_mine);
- swarmkv_cmd_free(keyspace_cmd);
- keyspace_cmd=NULL;
- assert(reply==NULL);
- assert(spec->auto_route==1);
- break;
- }
- default:
- {
- assert(0);
- break;
+ swarmkv_monitor_record_peer(db->mod_monitor, peer, latency_us, cur_tid);
}
+ swarmkv_msg_free(msg);
}
- db->threads[cur_tid].recusion_depth--;
- return;
}
-void command_register(struct swarmkv_cmd_spec **table, const char *name, const char *hint,
- int arity, int key_offset, enum cmd_key_flag flag, enum key_not_found_reply failover, int auto_route,
- command_proc_func *proc, struct swarmkv_module *module)
-{
- struct swarmkv_cmd_spec *spec=NULL;
-
- spec=ALLOC(struct swarmkv_cmd_spec, 1);
- spec->name=name;
- spec->hint=hint;
- spec->arity=arity;
- spec->key_offset=key_offset;
- spec->flag=flag;
- spec->nokey_reply=failover;
- spec->proc=proc;
- spec->auto_route=auto_route;
-
- spec->module=module;
- HASH_ADD_KEYPTR(hh, *table, spec->name, strlen(spec->name), spec);
- return;
-}
void command_spec_init(struct swarmkv *db)
{
- int AUTO_ROUTE=1, NOT_AUTO_ROUTE=0;
+ int AUTO_ROUTE = 1, NOT_AUTO_ROUTE = 0;
/* String and Integer commands*/
- command_register(&(db->command_table), "GET", "key",
- 1, 1, CMD_KEY_RO, REPLY_NIL, AUTO_ROUTE,
- get_command, db->mod_store);
- command_register(&(db->command_table), "SET", "key value",
- 2, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
- set_command, db->mod_store);
- command_register(&(db->command_table), "INCRBY", "key increment",
- 2, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
- incrby_command, db->mod_store);
- command_register(&(db->command_table), "INCR", "key",
- 1, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
- incr_command, db->mod_store);
- command_register(&(db->command_table), "DECR", "key",
- 1, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
- decr_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "GET", "key",
+ 1, 1, CMD_KEY_RO, REPLY_NIL, AUTO_ROUTE,
+ get_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "SET", "key value",
+ 2, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
+ set_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "INCRBY", "key increment",
+ 2, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
+ incrby_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "INCR", "key",
+ 1, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
+ incr_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "DECR", "key",
+ 1, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
+ decr_command, db->mod_store);
/* Generic commands*/
- command_register(&(db->command_table), "DEL", "key",
- 1, 1, CMD_KEY_RM, REPLY_INT_0, AUTO_ROUTE,
- del_command, db->mod_keyspace);
- command_register(&(db->command_table), "EXPIRE", "key seconds",
- 2, 1, CMD_KEY_RW, REPLY_INT_0, AUTO_ROUTE,
- expire_command, db->mod_keyspace);
- command_register(&(db->command_table), "TTL", "key",
- 1, 1, CMD_KEY_RO, REPLY_INT_MINORS1, AUTO_ROUTE,
- ttl_command, db->mod_keyspace);
- command_register(&(db->command_table), "PERSIST", "key",
- 1, 1, CMD_KEY_RW, REPLY_INT_0, AUTO_ROUTE,
- persist_command, db->mod_keyspace);
- command_register(&(db->command_table), "TYPE", "key",
- 1, 1, CMD_KEY_RO, REPLY_STR_NONE, AUTO_ROUTE,
- type_command, db->mod_store);
- command_register(&(db->command_table), "KEYSLOT", "key",
- 1, 1, CMD_KEY_RO, REPLY_ERROR, AUTO_ROUTE,
- keyslot_command, db->mod_keyspace);
+ swarmkv_command_table_register(db->mod_command_table, "DEL", "key",
+ 1, 1, CMD_KEY_RM, REPLY_INT_0, AUTO_ROUTE,
+ del_command, db->mod_keyspace);
+ swarmkv_command_table_register(db->mod_command_table, "EXPIRE", "key seconds",
+ 2, 1, CMD_KEY_RW, REPLY_INT_0, AUTO_ROUTE,
+ expire_command, db->mod_keyspace);
+ swarmkv_command_table_register(db->mod_command_table, "TTL", "key",
+ 1, 1, CMD_KEY_RO, REPLY_INT_MINORS1, AUTO_ROUTE,
+ ttl_command, db->mod_keyspace);
+ swarmkv_command_table_register(db->mod_command_table, "PERSIST", "key",
+ 1, 1, CMD_KEY_RW, REPLY_INT_0, AUTO_ROUTE,
+ persist_command, db->mod_keyspace);
+ swarmkv_command_table_register(db->mod_command_table, "TYPE", "key",
+ 1, 1, CMD_KEY_RO, REPLY_STR_NONE, AUTO_ROUTE,
+ type_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "KEYSLOT", "key",
+ 1, 1, CMD_KEY_RO, REPLY_ERROR, AUTO_ROUTE,
+ keyslot_command, db->mod_keyspace);
/* Set commands */
- command_register(&(db->command_table), "SADD", "key member [member ...]",
- 2, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
- sadd_command, db->mod_store);
- command_register(&(db->command_table), "SREM", "key member [member ...]",
- 2, 1, CMD_KEY_RW, REPLY_INT_0, AUTO_ROUTE,
- srem_command, db->mod_store);
- command_register(&(db->command_table), "SMEMBERS", "key",
- 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- smembers_command, db->mod_store);
- command_register(&(db->command_table), "SISMEMBER", "key member",
- 2, 1, CMD_KEY_RO, REPLY_INT_0, AUTO_ROUTE,
- sismember_command, db->mod_store);
- command_register(&(db->command_table), "SCARD", "key",
- 1, 1, CMD_KEY_RO, REPLY_INT_0, AUTO_ROUTE,
- scard_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "SADD", "key member [member ...]",
+ 2, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
+ sadd_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "SREM", "key member [member ...]",
+ 2, 1, CMD_KEY_RW, REPLY_INT_0, AUTO_ROUTE,
+ srem_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "SMEMBERS", "key",
+ 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ smembers_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "SISMEMBER", "key member",
+ 2, 1, CMD_KEY_RO, REPLY_INT_0, AUTO_ROUTE,
+ sismember_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "SCARD", "key",
+ 1, 1, CMD_KEY_RO, REPLY_INT_0, AUTO_ROUTE,
+ scard_command, db->mod_store);
/* Hash commands */
- command_register(&(db->command_table), "HSET", "key field value [field value ...]",
- 3, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
- hset_command, db->mod_store);
- command_register(&(db->command_table), "HGET", "key field",
- 2, 1, CMD_KEY_RO, REPLY_NIL, AUTO_ROUTE,
- hget_command, db->mod_store);
- command_register(&(db->command_table), "HMGET", "key field [field ...]",
- 2, 1, CMD_KEY_RO, REPLY_NIL, AUTO_ROUTE,
- hmget_command, db->mod_store);
- command_register(&(db->command_table), "HDEL", "key field [field ...]",
- 2, 1, CMD_KEY_RW, REPLY_INT_0, AUTO_ROUTE,
- hdel_command, db->mod_store);
- command_register(&(db->command_table), "HGETALL", "key",
- 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- hgetall_command, db->mod_store);
- command_register(&(db->command_table), "HLEN", "key",
- 1, 1, CMD_KEY_RO, REPLY_INT_0, AUTO_ROUTE,
- hlen_command, db->mod_store);
- command_register(&(db->command_table), "HKEYS", "key",
- 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- hkeys_command, db->mod_store);
- command_register(&(db->command_table), "HINCRBY", "key field increment",
- 3, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
- hincrby_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "HSET", "key field value [field value ...]",
+ 3, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
+ hset_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "HGET", "key field",
+ 2, 1, CMD_KEY_RO, REPLY_NIL, AUTO_ROUTE,
+ hget_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "HMGET", "key field [field ...]",
+ 2, 1, CMD_KEY_RO, REPLY_NIL, AUTO_ROUTE,
+ hmget_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "HDEL", "key field [field ...]",
+ 2, 1, CMD_KEY_RW, REPLY_INT_0, AUTO_ROUTE,
+ hdel_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "HGETALL", "key",
+ 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ hgetall_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "HLEN", "key",
+ 1, 1, CMD_KEY_RO, REPLY_INT_0, AUTO_ROUTE,
+ hlen_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "HKEYS", "key",
+ 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ hkeys_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "HINCRBY", "key field increment",
+ 3, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
+ hincrby_command, db->mod_store);
/* Token Buckets commands */
- command_register(&(db->command_table), "TCFG", "key rate capacity [PD seconds]",
- 3, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
- tcfg_command, db->mod_store);
- command_register(&(db->command_table), "TCONSUME", "key tokens [NORMAL|FORCE|FLEXIBLE]",
- 2, 1, CMD_KEY_RW, REPLY_INT_MINORS1, AUTO_ROUTE,
- tconsume_command, db->mod_store);
- command_register(&(db->command_table), "TINFO", "key",
- 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- tinfo_command, db->mod_store);
- command_register(&(db->command_table), "FTCFG", "key rate capacity divisor [PD seconds]",
- 4, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
- ftcfg_command, db->mod_store);
- command_register(&(db->command_table), "FTCONSUME", "key member weight tokens [NORMAL|FORCE|FLEXIBLE]",
- 4, 1, CMD_KEY_RW, REPLY_INT_MINORS1, AUTO_ROUTE,
- ftconsume_command, db->mod_store);
- command_register(&(db->command_table), "FTINFO", "key",
- 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- ftinfo_command, db->mod_store);
- command_register(&(db->command_table), "BTCFG", "key rate capacity initial-bucket-number [PD seconds]",
- 4, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
- btcfg_command, db->mod_store);
- command_register(&(db->command_table), "BTCONSUME", "key member tokens [NORMAL|FORCE|FLEXIBLE]",
- 3, 1, CMD_KEY_RW, REPLY_INT_MINORS1, AUTO_ROUTE,
- btconsume_command, db->mod_store);
- command_register(&(db->command_table), "BTINFO", "key",
- 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- btinfo_command, db->mod_store);
- command_register(&(db->command_table), "BTQUERY", "key member",
- 2, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- btquery_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "TCFG", "key rate capacity [PD seconds]",
+ 3, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
+ tcfg_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "TCONSUME", "key tokens [NORMAL|FORCE|FLEXIBLE]",
+ 2, 1, CMD_KEY_RW, REPLY_INT_MINORS1, AUTO_ROUTE,
+ tconsume_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "TINFO", "key",
+ 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ tinfo_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "FTCFG", "key rate capacity divisor [PD seconds]",
+ 4, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
+ ftcfg_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "FTCONSUME", "key member weight tokens [NORMAL|FORCE|FLEXIBLE]",
+ 4, 1, CMD_KEY_RW, REPLY_INT_MINORS1, AUTO_ROUTE,
+ ftconsume_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "FTINFO", "key",
+ 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ ftinfo_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "BTCFG", "key rate capacity initial-bucket-number [PD seconds]",
+ 4, 1, CMD_KEY_OW, REPLY_ERROR, AUTO_ROUTE,
+ btcfg_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "BTCONSUME", "key member tokens [NORMAL|FORCE|FLEXIBLE]",
+ 3, 1, CMD_KEY_RW, REPLY_INT_MINORS1, AUTO_ROUTE,
+ btconsume_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "BTINFO", "key",
+ 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ btinfo_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "BTQUERY", "key member",
+ 2, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ btquery_command, db->mod_store);
/*Bloom Filter commands*/
- command_register(&(db->command_table), "BFINIT", "key error capacity [TIME window-milliseconds slice-number]",
- 3, 1, CMD_KEY_OW, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- bfinit_command, db->mod_store);
- command_register(&(db->command_table), "BFADD", "key item [item ...]",
- 2, 1, CMD_KEY_RW, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- bfadd_command, db->mod_store);
- command_register(&(db->command_table), "BFEXISTS", "key item",
- 2, 1, CMD_KEY_RO, REPLY_INT_0, AUTO_ROUTE,
- bfexists_command, db->mod_store);
- command_register(&(db->command_table), "BFMEXISTS", "key item [item ...]",
- 2, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- bfmexists_command, db->mod_store);
- command_register(&(db->command_table), "BFCARD", "key",
- 1, 1, CMD_KEY_RO, REPLY_INT_0, AUTO_ROUTE,
- bfcard_command, db->mod_store);
- command_register(&(db->command_table), "BFINFO", "key",
- 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- bfinfo_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "BFINIT", "key error capacity [TIME window-milliseconds slice-number]",
+ 3, 1, CMD_KEY_OW, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ bfinit_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "BFADD", "key item [item ...]",
+ 2, 1, CMD_KEY_RW, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ bfadd_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "BFEXISTS", "key item",
+ 2, 1, CMD_KEY_RO, REPLY_INT_0, AUTO_ROUTE,
+ bfexists_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "BFMEXISTS", "key item [item ...]",
+ 2, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ bfmexists_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "BFCARD", "key",
+ 1, 1, CMD_KEY_RO, REPLY_INT_0, AUTO_ROUTE,
+ bfcard_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "BFINFO", "key",
+ 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ bfinfo_command, db->mod_store);
/*Count-min Sketch Commands*/
- command_register(&(db->command_table), "CMSINITBYDIM", "key width depth",
- 3, 1, CMD_KEY_OW, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- cmsinitbydim_command, db->mod_store);
- command_register(&(db->command_table), "CMSINITBYPROB", "key error probability",
- 3, 1, CMD_KEY_OW, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- cmsinitbyprob_command, db->mod_store);
- command_register(&(db->command_table), "CMSINCRBY", "key item increment [item increment ...]",
- 3, 1, CMD_KEY_RW, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- cmsincrby_command, db->mod_store);
- command_register(&(db->command_table), "CMSQUERY", "key item",
- 2, 1, CMD_KEY_RO, REPLY_INT_0, AUTO_ROUTE,
- cmsquery_command, db->mod_store);
- command_register(&(db->command_table), "CMSMQUERY", "key item [item ...]",
- 2, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- cmsmquery_command, db->mod_store);
- command_register(&(db->command_table), "CMSINFO", "key",
- 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- cmsinfo_command, db->mod_store);
- command_register(&(db->command_table), "CMSRLIST", "key",
- 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- cmsrlist_command, db->mod_store);
- command_register(&(db->command_table), "CMSRCLEAR", "key uuid",
- 2, 1, CMD_KEY_RW, REPLY_ERROR, AUTO_ROUTE,
- cmsrclear_command, db->mod_store);
-
+ swarmkv_command_table_register(db->mod_command_table, "CMSINITBYDIM", "key width depth",
+ 3, 1, CMD_KEY_OW, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ cmsinitbydim_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "CMSINITBYPROB", "key error probability",
+ 3, 1, CMD_KEY_OW, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ cmsinitbyprob_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "CMSINCRBY", "key item increment [item increment ...]",
+ 3, 1, CMD_KEY_RW, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ cmsincrby_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "CMSQUERY", "key item",
+ 2, 1, CMD_KEY_RO, REPLY_INT_0, AUTO_ROUTE,
+ cmsquery_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "CMSMQUERY", "key item [item ...]",
+ 2, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ cmsmquery_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "CMSINFO", "key",
+ 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ cmsinfo_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "CMSRLIST", "key",
+ 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ cmsrlist_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "CMSRCLEAR", "key uuid",
+ 2, 1, CMD_KEY_RW, REPLY_ERROR, AUTO_ROUTE,
+ cmsrclear_command, db->mod_store);
+
/*Hyperloglog Commands*/
- command_register(&(db->command_table), "PFINIT", "key precison [TIME window-milliseconds]",
- 2, 1, CMD_KEY_OW, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- pfinit_command, db->mod_store);
- command_register(&(db->command_table), "PFADD", "key item [item ...]",
- 2, 1, CMD_KEY_RW, REPLY_INT_MINORS1, AUTO_ROUTE,
- pfadd_command, db->mod_store);
- command_register(&(db->command_table), "PFCOUNT", "key",
- 1, 1, CMD_KEY_RO, REPLY_INT_MINORS1, AUTO_ROUTE,
- pfcount_command, db->mod_store);
- command_register(&(db->command_table), "PFINFO", "key",
- 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
- pfinfo_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "PFINIT", "key precison [TIME window-milliseconds]",
+ 2, 1, CMD_KEY_OW, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ pfinit_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "PFADD", "key item [item ...]",
+ 2, 1, CMD_KEY_RW, REPLY_INT_MINORS1, AUTO_ROUTE,
+ pfadd_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "PFCOUNT", "key",
+ 1, 1, CMD_KEY_RO, REPLY_INT_MINORS1, AUTO_ROUTE,
+ pfcount_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "PFINFO", "key",
+ 1, 1, CMD_KEY_RO, REPLY_EMPTY_ARRAY, AUTO_ROUTE,
+ pfinfo_command, db->mod_store);
/* Debug Commands */
- command_register(&(db->command_table), "INFO", "[section]",
- 0, KEY_OFFSET_NONE, CMD_KEY_NA, REPLY_NA, AUTO_ROUTE,
- info_command, &db->module);
- command_register(&(db->command_table), "DEBUG", "<subcommand>",
- 1, KEY_OFFSET_NONE, CMD_KEY_NA, REPLY_NA, AUTO_ROUTE,
- debug_command, &db->module);
- command_register(&(db->command_table), "PING", "IP:port",
- 1, KEY_OFFSET_NONE, CMD_KEY_NA, REPLY_NA, AUTO_ROUTE,
- ping_command, &db->module);
- command_register(&(db->command_table), "PRINT", "text",
- 1, KEY_OFFSET_NONE, CMD_KEY_NA, REPLY_NA, AUTO_ROUTE,
- print_command, &db->module);
- command_register(&(db->command_table), "COMMAND LIST", "",
- 0, KEY_OFFSET_NONE, CMD_KEY_NA, REPLY_NA, AUTO_ROUTE,
- command_list_command, &db->module);
- command_register(&(db->command_table), "LATENCY", "<subcommand>",
- 1, KEY_OFFSET_NONE, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
- latency_command, db->mod_monitor);
- command_register(&(db->command_table), "MONREG", "IP:port",
- 1, KEY_OFFSET_NONE, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
- monreg_command, db->mod_monitor);
-
+ swarmkv_command_table_register(db->mod_command_table, "INFO", "[section]",
+ 0, KEY_OFFSET_NONE, CMD_KEY_NA, REPLY_NA, AUTO_ROUTE,
+ info_command, &db->module);
+ swarmkv_command_table_register(db->mod_command_table, "DEBUG", "<subcommand>",
+ 1, KEY_OFFSET_NONE, CMD_KEY_NA, REPLY_NA, AUTO_ROUTE,
+ debug_command, &db->module);
+ swarmkv_command_table_register(db->mod_command_table, "PING", "IP:port",
+ 1, KEY_OFFSET_NONE, CMD_KEY_NA, REPLY_NA, AUTO_ROUTE,
+ ping_command, &db->module);
+ swarmkv_command_table_register(db->mod_command_table, "PRINT", "text",
+ 1, KEY_OFFSET_NONE, CMD_KEY_NA, REPLY_NA, AUTO_ROUTE,
+ print_command, &db->module);
+ swarmkv_command_table_register(db->mod_command_table, "COMMAND LIST", "",
+ 0, KEY_OFFSET_NONE, CMD_KEY_NA, REPLY_NA, AUTO_ROUTE,
+ command_list_command, db->mod_command_table);
+ swarmkv_command_table_register(db->mod_command_table, "LATENCY", "<subcommand>",
+ 1, KEY_OFFSET_NONE, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
+ latency_command, db->mod_monitor);
+ swarmkv_command_table_register(db->mod_command_table, "MONREG", "IP:port",
+ 1, KEY_OFFSET_NONE, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
+ monreg_command, db->mod_monitor);
+
/* low-level state-based CRDT synchronization commands*/
- command_register(&(db->command_table), "CRDT ADD", "key [IP:port ...]",
- 1, 2, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
- crdt_add_command, db->mod_store);
- command_register(&(db->command_table), "CRDT GET", "key",
- 1, 2, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
- crdt_get_command, db->mod_store);
- command_register(&(db->command_table), "CRDT MERGE", "key blob [key blob ...]",
- 2, 2, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
- crdt_merge_command, db->mod_store);
- command_register(&(db->command_table), "CRDT MEET", "key IP:port [IP:port ...]",
- 2, 2, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
- crdt_meet_command, db->mod_store);
- command_register(&(db->command_table), "CRDT DEL", "key",
- 1, 2, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
- crdt_del_command, db->mod_store);
- command_register(&(db->command_table), "CRDT KEYS", "tid pattern",
- 1, KEY_OFFSET_TID, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
- crdt_keys_command, db->mod_store);
- command_register(&(db->command_table), "CRDT EXISTS", "key",
- 1, 2, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
- crdt_exists_command, db->mod_store);
- command_register(&(db->command_table), "CRDT RLIST", "key",
- 1, 2, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
- crdt_rlist_command, db->mod_store);
- command_register(&(db->command_table), "CRDT INFO", "key",
- 1, 2, CMD_KEY_NA, REPLY_EMPTY_ARRAY, NOT_AUTO_ROUTE,
- crdt_info_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "CRDT ADD", "key [IP:port ...]",
+ 1, 2, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
+ crdt_add_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "CRDT GET", "key",
+ 1, 2, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
+ crdt_get_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "CRDT MERGE", "key blob [key blob ...]",
+ 2, 2, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
+ crdt_merge_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "CRDT MEET", "key IP:port [IP:port ...]",
+ 2, 2, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
+ crdt_meet_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "CRDT DEL", "key",
+ 1, 2, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
+ crdt_del_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "CRDT KEYS", "tid pattern",
+ 1, KEY_OFFSET_TID, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
+ crdt_keys_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "CRDT EXISTS", "key",
+ 1, 2, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
+ crdt_exists_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "CRDT RLIST", "key",
+ 1, 2, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
+ crdt_rlist_command, db->mod_store);
+ swarmkv_command_table_register(db->mod_command_table, "CRDT INFO", "key",
+ 1, 2, CMD_KEY_NA, REPLY_EMPTY_ARRAY, NOT_AUTO_ROUTE,
+ crdt_info_command, db->mod_store);
/* low-level keyspace operation commands */
- command_register(&(db->command_table), "KEYSPACE RLIST", "key",
- 1, 2, CMD_KEY_RO, REPLY_NA, AUTO_ROUTE,
- keyspace_rlist_command, db->mod_keyspace);
- command_register(&(db->command_table), "KEYSPACE RADD", "key [IP:port]",
- 1, 2, CMD_KEY_OW, REPLY_NA, AUTO_ROUTE,
- keyspace_radd_command, db->mod_keyspace);
- command_register(&(db->command_table), "KEYSPACE XRADD", "key IP:port",
- 2, 2, CMD_KEY_OW, REPLY_NA, AUTO_ROUTE,
- keyspace_xradd_command, db->mod_keyspace);
- command_register(&(db->command_table), "KEYSPACE KEYS", "tid pattern",//worker-thread-id
- 2, KEY_OFFSET_TID, CMD_KEY_RO, REPLY_NA, NOT_AUTO_ROUTE,
- keyspace_keys_command, db->mod_keyspace);
- command_register(&(db->command_table), "KEYSPACE RDEL", "key IP:port",
- 2, 2, CMD_KEY_RW, REPLY_NA, AUTO_ROUTE,
- keyspace_rdel_command, db->mod_keyspace);
- command_register(&(db->command_table), "KEYSPACE EXISTS", "key",
- 1, 2, CMD_KEY_RO, REPLY_NA, AUTO_ROUTE,
- keyspace_exists_command, db->mod_keyspace);
+ swarmkv_command_table_register(db->mod_command_table, "KEYSPACE RLIST", "key",
+ 1, 2, CMD_KEY_RO, REPLY_NA, AUTO_ROUTE,
+ keyspace_rlist_command, db->mod_keyspace);
+ swarmkv_command_table_register(db->mod_command_table, "KEYSPACE RADD", "key [IP:port]",
+ 1, 2, CMD_KEY_OW, REPLY_NA, AUTO_ROUTE,
+ keyspace_radd_command, db->mod_keyspace);
+ swarmkv_command_table_register(db->mod_command_table, "KEYSPACE XRADD", "key IP:port",
+ 2, 2, CMD_KEY_OW, REPLY_NA, AUTO_ROUTE,
+ keyspace_xradd_command, db->mod_keyspace);
+ swarmkv_command_table_register(db->mod_command_table, "KEYSPACE KEYS", "tid pattern", // worker-thread-id
+ 2, KEY_OFFSET_TID, CMD_KEY_RO, REPLY_NA, NOT_AUTO_ROUTE,
+ keyspace_keys_command, db->mod_keyspace);
+ swarmkv_command_table_register(db->mod_command_table, "KEYSPACE RDEL", "key IP:port",
+ 2, 2, CMD_KEY_RW, REPLY_NA, AUTO_ROUTE,
+ keyspace_rdel_command, db->mod_keyspace);
+ swarmkv_command_table_register(db->mod_command_table, "KEYSPACE EXISTS", "key",
+ 1, 2, CMD_KEY_RO, REPLY_NA, AUTO_ROUTE,
+ keyspace_exists_command, db->mod_keyspace);
/* low-level keyspace reorgnization commands */
- command_register(&(db->command_table), "KEYSPACE SETSLOT", "slot IMPORTING|MIGRATING|NODE|STABLE IP:port",
- 3, KEY_OFFSET_SLOTID, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
- keyspace_setslot_command, db->mod_keyspace);
- command_register(&(db->command_table), "KEYSPACE GETKEYSINSLOT", "slot",
- 1, KEY_OFFSET_SLOTID, CMD_KEY_RO, REPLY_NA, NOT_AUTO_ROUTE,
- keyspace_getkeysinslot_command, db->mod_keyspace);
- command_register(&(db->command_table), "KEYSPACE ADDKEYSTOSLOT", "slot blob",
- 2, KEY_OFFSET_SLOTID, CMD_KEY_OW, REPLY_NA, NOT_AUTO_ROUTE,
- keyspace_addkeystoslot_command, db->mod_keyspace);
- command_register(&(db->command_table), "KEYSPACE DELSLOTKEYS", "slot",
- 1, KEY_OFFSET_SLOTID, CMD_KEY_RM, REPLY_NA, NOT_AUTO_ROUTE,
- keyspace_delslotkeys_command, db->mod_keyspace);
- command_register(&(db->command_table), "KEYSPACE COUNTKEYSINSLOT", "slot",
- 1, KEY_OFFSET_SLOTID, CMD_KEY_RO, REPLY_NA, NOT_AUTO_ROUTE,
- keyspace_countkeysinslot_command, db->mod_keyspace);
+ swarmkv_command_table_register(db->mod_command_table, "KEYSPACE SETSLOT", "slot IMPORTING|MIGRATING|NODE|STABLE IP:port",
+ 3, KEY_OFFSET_SLOTID, CMD_KEY_NA, REPLY_NA, NOT_AUTO_ROUTE,
+ keyspace_setslot_command, db->mod_keyspace);
+ swarmkv_command_table_register(db->mod_command_table, "KEYSPACE GETKEYSINSLOT", "slot",
+ 1, KEY_OFFSET_SLOTID, CMD_KEY_RO, REPLY_NA, NOT_AUTO_ROUTE,
+ keyspace_getkeysinslot_command, db->mod_keyspace);
+ swarmkv_command_table_register(db->mod_command_table, "KEYSPACE ADDKEYSTOSLOT", "slot blob",
+ 2, KEY_OFFSET_SLOTID, CMD_KEY_OW, REPLY_NA, NOT_AUTO_ROUTE,
+ keyspace_addkeystoslot_command, db->mod_keyspace);
+ swarmkv_command_table_register(db->mod_command_table, "KEYSPACE DELSLOTKEYS", "slot",
+ 1, KEY_OFFSET_SLOTID, CMD_KEY_RM, REPLY_NA, NOT_AUTO_ROUTE,
+ keyspace_delslotkeys_command, db->mod_keyspace);
+ swarmkv_command_table_register(db->mod_command_table, "KEYSPACE COUNTKEYSINSLOT", "slot",
+ 1, KEY_OFFSET_SLOTID, CMD_KEY_RO, REPLY_NA, NOT_AUTO_ROUTE,
+ keyspace_countkeysinslot_command, db->mod_keyspace);
/* cluster commands are defined in swarmkv-cli.c */
return;
}
-const struct swarmkv_cmd_spec *get_spec_by_op_str(struct swarmkv *db, const char *op_str)
-{
- const struct swarmkv_cmd_spec *spec=NULL;
- char name[256]="", *p=NULL;
- size_t name_len=0;
- strncpy(name, op_str, sizeof(name));
- toLower(name);
- p=strchr(name, ' ');
- if(p)
- name_len=name-p;
- else
- name_len=strlen(name);
- HASH_FIND(hh, db->command_table, name, name_len, spec);
- if(spec)
- {
- return spec;
- }
- p=strchr(p, ' ');
- if(p)
- name_len=name-p;
- else
- name_len=strlen(name);
- HASH_FIND(hh, db->command_table, name, name_len, spec);
- if(spec)
- {
- return spec;
- }
- return NULL;
-}
-size_t swarmkv_get_possible_command_name(struct swarmkv *db, const char *prefix, const char* cmd_names[], size_t sz)
-{
- struct swarmkv_cmd_spec *spec=NULL, *tmp_spec=NULL;
- size_t n_matched=0;
- HASH_ITER(hh, db->command_table, spec, tmp_spec)
- {
- if(0==strncasecmp(spec->name, prefix, strlen(prefix)) && n_matched<sz)
- {
- cmd_names[n_matched]=spec->name;
- n_matched++;
- }
- }
- return n_matched;
-}
-char *swarmkv_get_command_hint(struct swarmkv *db, const char* cmd_name)
-{
- int argc, buflen = strlen(cmd_name);
- sds *argv = sdssplitargs(cmd_name,&argc);
- int endspace = buflen && isspace(cmd_name[buflen-1]);
-
- if (argc == 0)
- {
- sdsfreesplitres(argv,argc);
- return NULL;
- }
-
- size_t i;
- struct swarmkv_cmd_spec *spec=NULL, *tmp_spec=NULL;
- HASH_ITER(hh, db->command_table, spec, tmp_spec)
- {
- int argc_spec;
- sds *argv_spec = sdssplitargs(spec->name, &argc_spec);
- sds params=sdsdup(argv[0]);
- for(i=1; i<argc_spec && argc>=argc_spec; i++)
- {
- params = sdscatprintf(params, " %s", argv[i]);
- }
- sdsfreesplitres(argv_spec,argc_spec);
-
- if(0==strcasecmp(spec->name, params))
- {
- sds hint = sdsnew(spec->hint);
- int toremove = argc - argc_spec;
- while(toremove > 0 && sdslen(hint)) {
- if (hint[0] == '[') break;
- if (hint[0] == ' ') toremove--;
- sdsrange(hint,1,-1);
- }
-
- if (!endspace) {
- sds newhint = sdsnewlen(" ",1);
- newhint = sdscatsds(newhint,hint);
- sdsfree(hint);
- hint = newhint;
- }
- sdsfree(params);
- sdsfreesplitres(argv,argc);
- return hint;
- }
- sdsfree(params);
- }
- sdsfreesplitres(argv,argc);
- return NULL;
-}
static void evloop_timeout_cb(evutil_socket_t fd, short event, void *arg)
{
- struct swarmkv_thread *thr = (struct swarmkv_thread *)arg;
- event_base_loopbreak(thr->evbase);
+ struct swarmkv_thread *thr = (struct swarmkv_thread *)arg;
+ event_base_loopbreak(thr->evbase);
}
void swarmkv_caller_loop(struct swarmkv *db, int flags, struct timeval *tv)
{
- int tid=swarmkv_gettid(db);
- //must initiate from caller threads, and caller thread ID is larger than worker thread ID
+ int tid = swarmkv_gettid(db);
+ // must initiate from caller threads, and caller thread ID is larger than worker thread ID
assert(tid >= db->opts->nr_worker_threads);
- struct swarmkv_thread *thr=db->threads+tid;
+ struct swarmkv_thread *thr = db->threads + tid;
struct event *timeout_event = NULL;
- if(tv)
+ if (tv)
{
timeout_event = event_new(thr->evbase, -1, 0, evloop_timeout_cb, thr);
evtimer_add(timeout_event, tv);
@@ -1424,201 +1294,200 @@ void swarmkv_caller_loop(struct swarmkv *db, int flags, struct timeval *tv)
{
event_base_loop(thr->evbase, flags);
}
-
+
return;
}
void swarmkv_caller_loop_break(struct swarmkv *db)
{
- int tid=swarmkv_gettid(db);
- //must initiate from caller threads, and caller thread ID is larger than worker thread ID
+ int tid = swarmkv_gettid(db);
+ // must initiate from caller threads, and caller thread ID is larger than worker thread ID
assert(tid >= db->opts->nr_worker_threads);
event_base_loopbreak(db->ref_evbases[tid]);
}
long long swarmkv_caller_get_pending_commands(struct swarmkv *db)
{
- int tid=swarmkv_gettid(db);
- //must initiate from caller threads, and caller thread ID is larger than worker thread ID
+ int tid = swarmkv_gettid(db);
+ // must initiate from caller threads, and caller thread ID is larger than worker thread ID
assert(tid >= db->opts->nr_worker_threads);
return swarmkv_rpc_mgr_count(db->rpc_mgr, tid);
}
struct swarmkv *swarmkv_open(struct swarmkv_options *opts, const char *db_name, char **err)
{
struct swarmkv *db = NULL;
-// event_set_log_callback(libevent_log_cb);
- db=ALLOC(struct swarmkv, 1);
+ // event_set_log_callback(libevent_log_cb);
+ db = ALLOC(struct swarmkv, 1);
strncpy(db->db_name, db_name, sizeof(db->db_name));
- opts->total_threads=opts->nr_caller_threads+opts->nr_worker_threads;
- db->threads=ALLOC(struct swarmkv_thread, opts->total_threads);
- /* adds locking, only required if accessed from separate threads */
- //When accept a new connection, the worker thread 0 may create a bufferevent with evbase of other worker threads.
+ opts->total_threads = opts->nr_caller_threads + opts->nr_worker_threads;
+ db->threads = ALLOC(struct swarmkv_thread, opts->total_threads);
+ /* adds locking, only required if accessed from separate threads */
+ // When accept a new connection, the worker thread 0 may create a bufferevent with evbase of other worker threads.
evthread_use_pthreads();
- //evthread_enable_lock_debugging();
+ // evthread_enable_lock_debugging();
strncpy(db->module.name, "db", sizeof(db->module.name));
- db->module.mod_ctx=db;
+ db->module.mod_ctx = db;
- db->opts=opts;
- if(opts->logger)
+ db->opts = opts;
+ if (opts->logger)
{
- db->logger=opts->logger;
+ db->logger = opts->logger;
}
else
{
- char log_path[1024]="";
- if(opts->logpath)
- {
- snprintf(log_path, sizeof(log_path), "%s/%s.log", opts->logpath, db_name);
- }
- else
- {
- snprintf(log_path, sizeof(log_path), "%s.log", db_name);
- }
- db->logger=log_handle_create(log_path, opts->loglevel);
+ char log_path[1024] = "";
+ if (opts->logpath)
+ {
+ snprintf(log_path, sizeof(log_path), "%s/%s.log", opts->logpath, db_name);
+ }
+ else
+ {
+ snprintf(log_path, sizeof(log_path), "%s.log", db_name);
+ }
+ db->logger = log_handle_create(log_path, opts->loglevel);
}
- if(opts->dryrun)
+ if (opts->dryrun)
{
}
- db->ref_evbases=ALLOC(struct event_base*, opts->total_threads);
- struct event_config *ev_cfg=event_config_new();
- int ret=event_config_set_max_dispatch_interval(ev_cfg, opts->eb_max_interval, opts->eb_max_callbacks, 0);
- assert(ret==0);
- for(int i=0; i<opts->total_threads; i++)
+ db->ref_evbases = ALLOC(struct event_base *, opts->total_threads);
+ struct event_config *ev_cfg = event_config_new();
+ int ret = event_config_set_max_dispatch_interval(ev_cfg, opts->eb_max_interval, opts->eb_max_callbacks, 0);
+ assert(ret == 0);
+ for (int i = 0; i < opts->total_threads; i++)
{
- if(i>opts->nr_worker_threads)
+ if (i > opts->nr_worker_threads)
{
- db->threads[i].evbase=event_base_new_with_config(ev_cfg);
+ db->threads[i].evbase = event_base_new_with_config(ev_cfg);
event_base_priority_init(db->threads[i].evbase, 2);
}
else
{
- db->threads[i].evbase=event_base_new();
+ db->threads[i].evbase = event_base_new();
}
- db->threads[i].db=db;
- db->ref_evbases[i]=db->threads[i].evbase;
+ db->threads[i].db = db;
+ db->ref_evbases[i] = db->threads[i].evbase;
}
event_config_free(ev_cfg);
- db->mod_monitor=swarmkv_monitor_new(db->opts, db);
+ db->mod_monitor = swarmkv_monitor_new(db->opts, db);
- db->rpc_mgr=swarmkv_rpc_mgr_new(db->ref_evbases, opts->total_threads, opts->cluster_timeout_us);
- db->mesh=swarmkv_mesh_new(db->ref_evbases, opts->total_threads, db->logger);
- swarmkv_mesh_set_on_msg_cb(db->mesh, __on_msg_callback, db);
-
+ db->rpc_mgr = swarmkv_rpc_mgr_new(db->ref_evbases, opts->total_threads, opts->cluster_timeout_us);
+ db->mesh = swarmkv_mesh_new(db->ref_evbases, opts->total_threads, db->logger);
+ swarmkv_mesh_set_on_msg_cb(db->mesh, __on_mesh_msg_callback, db);
- //Note: if the cluster_port is 0, swarmkv_net_new updates db->self.cluster_port.
- db->net=swarmkv_net_new(db->ref_evbases, db->opts->nr_worker_threads, opts, db->logger, err);
- if(*err)
+ // Note: if the cluster_port is 0, swarmkv_net_new updates db->self.cluster_port.
+ db->net = swarmkv_net_new(db->ref_evbases, opts->total_threads, opts, db->logger, err);
+ if (*err)
{
goto error_out;
}
- swarmkv_net_set_on_msg_callback(db->net, __on_msg_callback, db);
+ swarmkv_net_set_on_msg_callback(db->net, __on_net_msg_callback, db);
swarmkv_net_set_monitor_handle(db->net, db->mod_monitor);
node_init(&db->self, opts->cluster_announce_ip, opts->cluster_announce_port);
-
- db->mod_keyspace=swarmkv_keyspace_new(db->ref_evbases, db->opts->nr_worker_threads, db->opts, db_name, db->logger, err);
- if(*err)
+ db->mod_keyspace = swarmkv_keyspace_new(db->ref_evbases, db->opts->nr_worker_threads, db->opts, db_name, db->logger, err);
+ if (*err)
{
goto error_out;
}
swarmkv_keyspace_set_exec_cmd_handle(db->mod_keyspace, db);
swarmkv_keyspace_set_monitor_handle(db->mod_keyspace, db->mod_monitor);
- db->mod_store=swarmkv_store_new(db->opts);
+ db->mod_store = swarmkv_store_new(db->opts);
swarmkv_store_set_exec_cmd_handle(db->mod_store, db);
swarmkv_store_set_monitor_handle(db->mod_store, db->mod_monitor);
+ db->mod_command_table = swarmkv_command_table_new();
command_spec_init(db);
- struct swarmkv_cmd_spec *spec=NULL, *tmp_spec=NULL;
- HASH_ITER(hh, db->command_table, spec, tmp_spec)
+ size_t n_cmd = swarmkv_command_table_count(db->mod_command_table);
+ const char **cmd_names = ALLOC(const char *, n_cmd);
+ size_t ret_n_cmd = swarmkv_command_table_list_names(db->mod_command_table, cmd_names, n_cmd);
+ assert(ret_n_cmd == n_cmd);
+ for (size_t i = 0; i < n_cmd; i++)
{
- swarmkv_monitor_register_command(db->mod_monitor, spec->name);
+ swarmkv_monitor_register_command(db->mod_monitor, cmd_names[i]);
}
+ free(cmd_names);
+
swarmkv_monitor_register_event(db->mod_monitor, MONITOR_INTER_THREAD_RPC);
swarmkv_threads_run(db);
-
+
swarmkv_keyspace_start(db->mod_keyspace);
- char str_uuid[37]="";
+ char str_uuid[37] = "";
uuid_unparse(db->opts->bin_uuid, str_uuid);
- opts->is_assigned_to_db=1;
+ opts->is_assigned_to_db = 1;
clock_gettime(CLOCK_MONOTONIC, &db->boot_time);
log_info(db->logger, MODULE_SWAMRKV_CORE, "swarmkv instance %s of cluster %s is opened.", str_uuid, db->db_name);
return db;
+
error_out:
- if(db->net)
+ if (db->net)
{
swarmkv_net_free(db->net);
- db->net=NULL;
+ db->net = NULL;
}
- if(db->mod_keyspace)
+ if (db->mod_keyspace)
{
swarmkv_keyspace_free(db->mod_keyspace);
- db->mod_keyspace=NULL;
+ db->mod_keyspace = NULL;
}
swarmkv_options_free(db->opts);
- db->opts=NULL;
+ db->opts = NULL;
free(db);
- db=NULL;
+ db = NULL;
return NULL;
}
-void swarmkv_close(struct swarmkv * db)
+void swarmkv_close(struct swarmkv *db)
{
- for(size_t i=0; i<db->opts->total_threads; i++)
+ for (size_t i = 0; i < db->opts->total_threads; i++)
{
- event_base_loopexit(db->threads[i].evbase, NULL);
- db->threads[i].is_dispatching=0;
+ event_base_loopexit(db->threads[i].evbase, NULL);
+ db->threads[i].is_dispatching = 0;
}
- for(size_t i=0; i<db->opts->nr_worker_threads; i++)
+ for (size_t i = 0; i < db->opts->nr_worker_threads; i++)
{
pthread_join(db->threads[i].thr, NULL);
}
swarmkv_rpc_mgr_free(db->rpc_mgr);
- db->rpc_mgr=NULL;
+ db->rpc_mgr = NULL;
swarmkv_monitor_free(db->mod_monitor);
- db->mod_monitor=NULL;
+ db->mod_monitor = NULL;
swarmkv_store_free(db->mod_store);
- db->mod_store=NULL;
+ db->mod_store = NULL;
swarmkv_keyspace_free(db->mod_keyspace);
- db->mod_keyspace=NULL;
+ db->mod_keyspace = NULL;
+ swarmkv_command_table_free(db->mod_command_table);
+ db->mod_command_table = NULL;
swarmkv_mesh_free(db->mesh);
- db->mesh=NULL;
+ db->mesh = NULL;
swarmkv_net_free(db->net);
- db->net=NULL;
-
+ db->net = NULL;
- struct swarmkv_cmd_spec *spec=NULL, *tmp_spec=NULL;
-
- HASH_ITER(hh, db->command_table, spec, tmp_spec)
- {
- HASH_DEL(db->command_table, spec);
- free(spec);
- }
- char str_uuid[37]="";
+ char str_uuid[37] = "";
uuid_unparse(db->opts->bin_uuid, str_uuid);
log_info(db->logger, MODULE_SWAMRKV_CORE, "swarmkv instance %s of cluster %s is closed.", str_uuid, db->db_name);
- if(db->opts->logger != db->logger)
+ if (db->opts->logger != db->logger)
{
log_handle_destroy(db->logger);
- db->logger=NULL;
+ db->logger = NULL;
}
- for(size_t i=0; i<db->opts->total_threads; i++)
+ for (size_t i = 0; i < db->opts->total_threads; i++)
{
event_base_free(db->threads[i].evbase);
}
free(db->threads);
- db->threads=NULL;
+ db->threads = NULL;
free(db->ref_evbases);
- db->ref_evbases=NULL;
+ db->ref_evbases = NULL;
- db->opts->is_assigned_to_db=0;
+ db->opts->is_assigned_to_db = 0;
swarmkv_options_free(db->opts);
- db->opts=NULL;
+ db->opts = NULL;
pthread_barrier_destroy(&db->barrier);
free(db);
return;
@@ -1635,4 +1504,12 @@ void swarmkv_self_uuid(const struct swarmkv *db, char buff[37])
{
uuid_unparse(db->opts->bin_uuid, buff);
return;
+}
+size_t swarmkv_get_possible_command_name(struct swarmkv *db, const char *prefix, const char *cmd_names[], size_t sz)
+{
+ return swarmkv_command_table_find_possible_names(db->mod_command_table, prefix, cmd_names, sz);
+}
+char *swarmkv_get_command_hint(struct swarmkv *db, const char *cmd_name)
+{
+ return swarmkv_command_table_get_command_hint(db->mod_command_table, cmd_name);
} \ No newline at end of file
diff --git a/src/swarmkv_api.c b/src/swarmkv_api.c
index c5772ac..882721f 100644
--- a/src/swarmkv_api.c
+++ b/src/swarmkv_api.c
@@ -7,82 +7,82 @@
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
-#define MODULE_SWAMRKV_API module_name_str("swarmkv.api")
+#define MODULE_SWAMRKV_API module_name_str("swarmkv.api")
-void exec_for_local(struct swarmkv *db, const struct swarmkv_cmd *cmd, const node_t *target_node, swarmkv_on_reply_callback_t * cb, void * cb_arg);
const node_t *swarmkv_self_node(const struct swarmkv *db);
struct swarmkv_readoptions
{
-
};
struct swarmkv_writeoptions
{
-
};
-struct swarmkv_options* swarmkv_options_new(void)
-{
- struct swarmkv_options *opts=ALLOC(struct swarmkv_options, 1);
- opts->consul_port=8500;
- opts->cluster_port=5210;
- opts->health_check_port=0;
- opts->loglevel=0;
- opts->cluster_timeout_us=500*1000;//Default 500ms
- opts->sync_interval_us=10*1000; //Default 10ms
+struct swarmkv_options *swarmkv_options_new(void)
+{
+ struct swarmkv_options *opts = ALLOC(struct swarmkv_options, 1);
+ opts->consul_port = 8500;
+ opts->cluster_port = 5210;
+ opts->health_check_port = 0;
+ opts->loglevel = 0;
+ opts->cluster_timeout_us = 500 * 1000; // Default 500ms
+ opts->sync_interval_us = 10 * 1000; // Default 10ms
strcpy(opts->bind_address, "0.0.0.0");
strcpy(opts->cluster_announce_ip, "127.0.0.1");
strcpy(opts->consul_agent_host, "127.0.0.1");
uuid_generate(opts->bin_uuid);
- opts->nr_worker_threads=1;
- opts->nr_caller_threads=1;
- opts->is_assigned_to_db=0;
- opts->run_for_leader_enabled=1;
- opts->batch_sync_enabled=0;
- opts->eb_max_callbacks=-1;
- opts->eb_max_interval=NULL;
+ opts->dryrun = 0;
+ opts->network_compression_enabled = 1;
+ opts->nr_worker_threads = 1;
+ opts->nr_caller_threads = 1;
+ opts->is_assigned_to_db = 0;
+ opts->run_for_leader_enabled = 1;
+ opts->batch_sync_enabled = 0;
+ opts->eb_max_callbacks = -1;
+ opts->eb_max_interval = NULL;
return opts;
}
void swarmkv_options_free(struct swarmkv_options *opt)
{
- if(opt->is_assigned_to_db)
+ if (opt->is_assigned_to_db)
{
assert(0);
}
else
{
- if(opt->eb_max_interval) free(opt->eb_max_interval);
+ if (opt->eb_max_interval)
+ free(opt->eb_max_interval);
free(opt);
}
return;
}
int swarmkv_options_set_cluster_port(struct swarmkv_options *opts, unsigned int cluster_port)
{
- opts->cluster_port=cluster_port;
+ opts->cluster_port = cluster_port;
return 0;
}
int swarmkv_options_set_cluster_announce_port(struct swarmkv_options *opts, unsigned int cluster_announce_port)
{
- opts->cluster_announce_port=cluster_announce_port;
+ opts->cluster_announce_port = cluster_announce_port;
return 0;
}
int swarmkv_options_set_health_check_port(struct swarmkv_options *opts, unsigned int health_check_port)
{
- opts->health_check_port=health_check_port;
+ opts->health_check_port = health_check_port;
return 0;
}
int swarmkv_options_set_health_check_announce_port(struct swarmkv_options *opts, unsigned int health_check_announce_port)
{
- opts->health_check_announce_port=health_check_announce_port;
+ opts->health_check_announce_port = health_check_announce_port;
return 0;
}
int swarmkv_options_set_cluster_timeout_us(struct swarmkv_options *opts, unsigned int timeout_us)
{
- opts->cluster_timeout_us=timeout_us;
+ opts->cluster_timeout_us = timeout_us;
return 0;
}
int swarmkv_options_set_sync_interval_us(struct swarmkv_options *opts, unsigned int interval_us)
{
- opts->sync_interval_us=interval_us;
+ opts->sync_interval_us = interval_us;
return 0;
}
int swarmkv_options_set_bind_address(struct swarmkv_options *opts, const char *ip_addr)
@@ -97,52 +97,57 @@ int swarmkv_options_set_cluster_announce_ip(struct swarmkv_options *opts, const
}
int swarmkv_options_set_logger(struct swarmkv_options *opts, void *logger)
{
- opts->logger=logger;
+ opts->logger = logger;
return 0;
}
int swarmkv_options_set_log_level(struct swarmkv_options *opts, int loglevel)
{
- opts->loglevel=loglevel;
- return 0;
+ opts->loglevel = loglevel;
+ return 0;
}
int swarmkv_options_set_log_path(struct swarmkv_options *opts, const char *logpath)
{
- opts->logpath=logpath;
- return 0;
+ opts->logpath = logpath;
+ return 0;
}
int swarmkv_options_set_run_for_leader_enabled(struct swarmkv_options *opts, int value)
{
- opts->run_for_leader_enabled=value;
+ opts->run_for_leader_enabled = value;
return 0;
}
-int swarmkv_options_set_consul_host(struct swarmkv_options *opts, const char* ip_addr)
+int swarmkv_options_set_consul_host(struct swarmkv_options *opts, const char *ip_addr)
{
strncpy(opts->consul_agent_host, ip_addr, sizeof(opts->consul_agent_host));
return 0;
}
int swarmkv_options_set_consul_port(struct swarmkv_options *opts, unsigned int consul_port)
{
- opts->consul_port=consul_port;
+ opts->consul_port = consul_port;
return 0;
}
int swarmkv_options_set_dryrun(struct swarmkv_options *opts)
{
- opts->dryrun=1;
+ opts->dryrun = 1;
return 0;
}
int swarmkv_options_set_caller_thread_number(struct swarmkv_options *opts, int nr_caller_threads)
{
- opts->nr_caller_threads=nr_caller_threads;
+ opts->nr_caller_threads = nr_caller_threads;
return 0;
}
int swarmkv_options_set_worker_thread_number(struct swarmkv_options *opts, int nr_worker_threads)
{
- opts->nr_worker_threads=nr_worker_threads;
+ opts->nr_worker_threads = nr_worker_threads;
return 0;
}
int swarmkv_options_set_batch_sync_enabled(struct swarmkv_options *opts, int value)
{
- opts->batch_sync_enabled=1;
+ opts->batch_sync_enabled = 1;
+ return 0;
+}
+int swarmkv_options_set_network_compression_enabled(struct swarmkv_options *opts, int value)
+{
+ opts->network_compression_enabled = value;
return 0;
}
int swarmkv_options_get_worker_thread_number(const struct swarmkv_options *opts)
@@ -151,46 +156,46 @@ int swarmkv_options_get_worker_thread_number(const struct swarmkv_options *opts)
}
int swarmkv_options_set_max_dispatch_interval(struct swarmkv_options *opts, const struct timeval *max_interval, int max_callbacks)
{
- if(max_interval)
+ if (max_interval)
{
- opts->eb_max_interval=ALLOC(struct timeval, 1);
+ opts->eb_max_interval = ALLOC(struct timeval, 1);
memcpy(opts->eb_max_interval, max_interval, sizeof(struct timeval));
}
- opts->eb_max_callbacks=max_callbacks;
+ opts->eb_max_callbacks = max_callbacks;
return 0;
}
-void swarmkv_async_command_on_argv(struct swarmkv *db, swarmkv_on_reply_callback_t * cb, void *cb_arg, const char *target, int argc, const char *argv[], size_t *argv_len)
+extern void exec_for_local(struct swarmkv *db, const struct swarmkv_cmd *cmd, node_t *peer, swarmkv_on_reply_callback_t *cb, void *cb_arg);
+void swarmkv_async_command_on_argv(struct swarmkv *db, swarmkv_on_reply_callback_t *cb, void *cb_arg, const char *target, int argc, const char *argv[], size_t *argv_len)
{
- struct swarmkv_cmd *cmd=NULL;
- cmd=swarmkv_cmd_new(argc, swarmkv_self_node(db));
- for(size_t i=0; i<argc; i++)
+ struct swarmkv_cmd *cmd = NULL;
+ cmd = swarmkv_cmd_new(argc, swarmkv_self_node(db));
+ for (size_t i = 0; i < argc; i++)
{
assert(argv[i]);
- assert(argv_len[i]>0);
- cmd->argv[i]=sdsnewlen(argv[i], argv_len[i]);
+ assert(argv_len[i] > 0);
+ cmd->argv[i] = sdsnewlen(argv[i], argv_len[i]);
}
- if(!target)
- {
- exec_for_local(db, cmd, NULL, cb, cb_arg);
- }
- else
- {
+ if (target)
+ {
node_t target_node;
- memset(&target_node, 0, sizeof(node_t));
node_init_from_sds(&target_node, target);
- exec_for_local(db, cmd, &target_node, cb, cb_arg);
- }
- swarmkv_cmd_free(cmd);
+ exec_for_local(db, cmd, &target_node, cb, cb_arg);
+ }
+ else
+ {
+ exec_for_local(db, cmd, NULL, cb, cb_arg);
+ }
+ swarmkv_cmd_free(cmd);
}
struct blocking_query_ctx
{
struct swarmkv_reply *reply;
struct swarmkv *db;
};
-void blocking_query_cb(const struct swarmkv_reply *reply, void * arg)
+void blocking_query_cb(const struct swarmkv_reply *reply, void *arg)
{
- struct blocking_query_ctx *ctx=(struct blocking_query_ctx*) arg;
- ctx->reply=swarmkv_reply_dup(reply);
+ struct blocking_query_ctx *ctx = (struct blocking_query_ctx *)arg;
+ ctx->reply = swarmkv_reply_dup(reply);
swarmkv_caller_loop_break(ctx->db);
return;
}
@@ -198,45 +203,45 @@ struct swarmkv_reply *swarmkv_command_on_argv(struct swarmkv *db, const char *ta
{
struct blocking_query_ctx ctx;
memset(&ctx, 0, sizeof(ctx));
- ctx.db=db;
- ctx.reply=NULL;
+ ctx.db = db;
+ ctx.reply = NULL;
swarmkv_async_command_on_argv(db, blocking_query_cb, &ctx, target, argc, argv, argv_len);
- long long pending_cmds=0;
- pending_cmds=swarmkv_caller_get_pending_commands(db);
- if(ctx.reply==NULL)
+ long long pending_cmds = 0;
+ pending_cmds = swarmkv_caller_get_pending_commands(db);
+ if (ctx.reply == NULL)
{
- assert(pending_cmds==1);
+ assert(pending_cmds == 1);
swarmkv_caller_loop(db, SWARMKV_LOOP_NO_EXIT_ON_EMPTY, NULL);
}
- assert(ctx.reply!=NULL);
- struct swarmkv_reply *reply=NULL;
- reply=ctx.reply;
- ctx.reply=NULL;
+ assert(ctx.reply != NULL);
+ struct swarmkv_reply *reply = NULL;
+ reply = ctx.reply;
+ ctx.reply = NULL;
return reply;
}
struct swarmkv_reply *swarmkv_command_on(struct swarmkv *db, const char *target, const char *format, ...)
{
- char *cmd_str=NULL;
+ char *cmd_str = NULL;
va_list ap;
va_start(ap, format);
vasprintf(&cmd_str, format, ap);
va_end(ap);
- int argc=0;
- sds *argv=NULL;
+ int argc = 0;
+ sds *argv = NULL;
- argv=sdssplitargs(cmd_str, &argc);
+ argv = sdssplitargs(cmd_str, &argc);
size_t argv_len[argc];
- for(int i=0; i<argc; i++)
+ for (int i = 0; i < argc; i++)
{
- argv_len[i]=sdslen(argv[i]);
+ argv_len[i] = sdslen(argv[i]);
}
- struct swarmkv_reply *reply=NULL;
- reply=swarmkv_command_on_argv(db, target, argc, (const char**) argv, argv_len);
+ struct swarmkv_reply *reply = NULL;
+ reply = swarmkv_command_on_argv(db, target, argc, (const char **)argv, argv_len);
- if (argv)
+ if (argv)
{
- sdsfreesplitres(argv, argc);
+ sdsfreesplitres(argv, argc);
}
free(cmd_str);
@@ -244,34 +249,35 @@ struct swarmkv_reply *swarmkv_command_on(struct swarmkv *db, const char *target,
}
struct swarmkv_reply *swarmkv_command(struct swarmkv *db, const char *format, ...)
{
- struct swarmkv_reply *reply=NULL;
- char *cmd_str=NULL;
+ struct swarmkv_reply *reply = NULL;
+ char *cmd_str = NULL;
va_list ap;
va_start(ap, format);
vasprintf(&cmd_str, format, ap);
va_end(ap);
- reply=swarmkv_command_on(db, NULL, cmd_str);
+ reply = swarmkv_command_on(db, NULL, cmd_str);
free(cmd_str);
return reply;
}
-void swarmkv_async_command_on(struct swarmkv *db, swarmkv_on_reply_callback_t * cb, void *cb_arg, const char *target, const char *format, ...)
+void swarmkv_async_command_on(struct swarmkv *db, swarmkv_on_reply_callback_t *cb, void *cb_arg, const char *target, const char *format, ...)
{
- int argc=0; sds *argv=NULL;
- char *cmd_str=NULL;
+ int argc = 0;
+ sds *argv = NULL;
+ char *cmd_str = NULL;
va_list ap;
va_start(ap, format);
vasprintf(&cmd_str, format, ap);
va_end(ap);
- argv=sdssplitargs(cmd_str, &argc);
+ argv = sdssplitargs(cmd_str, &argc);
size_t argv_len[argc];
- for(size_t i=0; i<argc; i++)
+ for (size_t i = 0; i < argc; i++)
{
- argv_len[i]=sdslen(argv[i]);
+ argv_len[i] = sdslen(argv[i]);
}
- swarmkv_async_command_on_argv(db, cb, cb_arg, target, argc, (const char**)argv, argv_len);
+ swarmkv_async_command_on_argv(db, cb, cb_arg, target, argc, (const char **)argv, argv_len);
if (argv)
{
@@ -279,40 +285,40 @@ void swarmkv_async_command_on(struct swarmkv *db, swarmkv_on_reply_callback_t *
}
free(cmd_str);
}
-void swarmkv_async_command(struct swarmkv *db, swarmkv_on_reply_callback_t * cb, void *cb_arg, const char *format, ...)
+void swarmkv_async_command(struct swarmkv *db, swarmkv_on_reply_callback_t *cb, void *cb_arg, const char *format, ...)
{
- char *cmd_str=NULL;
+ char *cmd_str = NULL;
va_list ap;
- va_start(ap,format);
+ va_start(ap, format);
vasprintf(&cmd_str, format, ap);
va_end(ap);
swarmkv_async_command_on(db, cb, cb_arg, NULL, cmd_str);
- free(cmd_str);
+ free(cmd_str);
}
-void swarmkv_set(struct swarmkv * db,
- const char * key, size_t keylen, const char * value, size_t vallen, swarmkv_on_reply_callback_t * cb, void * cb_arg)
+void swarmkv_set(struct swarmkv *db,
+ const char *key, size_t keylen, const char *value, size_t vallen, swarmkv_on_reply_callback_t *cb, void *cb_arg)
{
const char *argv[3];
size_t argv_len[3];
- argv[0]="set";
- argv_len[0]=4;
- argv[1]=key;
- argv_len[1]=keylen;
- argv[2]=value;
- argv_len[2]=vallen;
+ argv[0] = "set";
+ argv_len[0] = 4;
+ argv[1] = key;
+ argv_len[1] = keylen;
+ argv[2] = value;
+ argv_len[2] = vallen;
swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 3, argv, argv_len);
return;
}
-void swarmkv_get(struct swarmkv * db,
- const char *key, size_t keylen, swarmkv_on_reply_callback_t *cb, void *cb_arg)
+void swarmkv_get(struct swarmkv *db,
+ const char *key, size_t keylen, swarmkv_on_reply_callback_t *cb, void *cb_arg)
{
const char *argv[2];
size_t argv_len[2];
- argv[0]="get";
- argv_len[0]=4;
- argv[1]=key;
- argv_len[1]=keylen;
+ argv[0] = "get";
+ argv_len[0] = 4;
+ argv[1] = key;
+ argv_len[1] = keylen;
swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2, argv, argv_len);
return;
}
@@ -320,14 +326,14 @@ void swarmkv_expire(struct swarmkv *db, const char *key, size_t keylen, int seco
{
const char *argv[3];
size_t argv_len[3];
- argv[0]="expire";
- argv_len[0]=strlen(argv[0]);
- argv[1]=key;
- argv_len[1]=keylen;
+ argv[0] = "expire";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = key;
+ argv_len[1] = keylen;
char buffer[32];
sprintf(buffer, "%d", seconds);
- argv[2]=buffer;
- argv_len[2]=strlen(buffer);
+ argv[2] = buffer;
+ argv_len[2] = strlen(buffer);
swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 3, argv, argv_len);
return;
}
@@ -335,10 +341,10 @@ void swarmkv_ttl(struct swarmkv *db, const char *key, size_t keylen, swarmkv_on_
{
const char *argv[2];
size_t argv_len[2];
- argv[0]="ttl";
- argv_len[0]=4;
- argv[1]=key;
- argv_len[1]=keylen;
+ argv[0] = "ttl";
+ argv_len[0] = 4;
+ argv[1] = key;
+ argv_len[1] = keylen;
swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2, argv, argv_len);
return;
}
@@ -347,230 +353,230 @@ void swarmkv_persist(struct swarmkv *db, const char *key, size_t keylen, swarmkv
{
const char *argv[2];
size_t argv_len[2];
- argv[0]="persist";
- argv_len[0]=strlen(argv[0]);
- argv[1]=key;
- argv_len[1]=keylen;
+ argv[0] = "persist";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = key;
+ argv_len[1] = keylen;
swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2, argv, argv_len);
return;
}
-void swarmkv_sadd(struct swarmkv *db, const char* key, size_t keylen, const char *members[], const size_t members_len[], size_t n_members, swarmkv_on_reply_callback_t *cb, void *cb_arg)
+void swarmkv_sadd(struct swarmkv *db, const char *key, size_t keylen, const char *members[], const size_t members_len[], size_t n_members, swarmkv_on_reply_callback_t *cb, void *cb_arg)
{
- const char *argv[2+n_members];
- size_t argv_len[2+n_members];
- argv[0]="sadd";
- argv_len[0]=strlen(argv[0]);
- argv[1]=key;
- argv_len[1]=keylen;
- for(size_t i=0; i<n_members; i++)
+ const char *argv[2 + n_members];
+ size_t argv_len[2 + n_members];
+ argv[0] = "sadd";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = key;
+ argv_len[1] = keylen;
+ for (size_t i = 0; i < n_members; i++)
{
- argv[2+i]=members[i];
- argv_len[2+i]=members_len[i];
+ argv[2 + i] = members[i];
+ argv_len[2 + i] = members_len[i];
}
- swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2+n_members, argv, argv_len);
+ swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2 + n_members, argv, argv_len);
return;
}
-void swarmkv_srem(struct swarmkv *db, const char* key, size_t keylen, const char *members[], const size_t members_len[], size_t n_members, swarmkv_on_reply_callback_t *cb, void *cb_arg)
+void swarmkv_srem(struct swarmkv *db, const char *key, size_t keylen, const char *members[], const size_t members_len[], size_t n_members, swarmkv_on_reply_callback_t *cb, void *cb_arg)
{
- const char *argv[2+n_members];
- size_t argv_len[2+n_members];
- argv[0]="srem";
- argv_len[0]=strlen(argv[0]);
- argv[1]=key;
- argv_len[1]=keylen;
- for(size_t i=0; i<n_members; i++)
+ const char *argv[2 + n_members];
+ size_t argv_len[2 + n_members];
+ argv[0] = "srem";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = key;
+ argv_len[1] = keylen;
+ for (size_t i = 0; i < n_members; i++)
{
- argv[2+i]=members[i];
- argv_len[2+i]=members_len[i];
+ argv[2 + i] = members[i];
+ argv_len[2 + i] = members_len[i];
}
- swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2+n_members, argv, argv_len);
+ swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2 + n_members, argv, argv_len);
return;
}
-void swarmkv_sismember(struct swarmkv *db, const char* key, size_t keylen, const char *member, size_t member_len, swarmkv_on_reply_callback_t *cb, void *cb_arg)
+void swarmkv_sismember(struct swarmkv *db, const char *key, size_t keylen, const char *member, size_t member_len, swarmkv_on_reply_callback_t *cb, void *cb_arg)
{
const char *argv[3];
size_t argv_len[3];
- argv[0]="sismember";
- argv_len[0]=strlen(argv[0]);
- argv[1]=key;
- argv_len[1]=keylen;
- argv[2]=member;
- argv_len[2]=member_len;
+ argv[0] = "sismember";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = key;
+ argv_len[1] = keylen;
+ argv[2] = member;
+ argv_len[2] = member_len;
swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 3, argv, argv_len);
return;
}
-void swarmkv_smembers(struct swarmkv *db, const char* key, size_t keylen, swarmkv_on_reply_callback_t *cb, void *cb_arg)
+void swarmkv_smembers(struct swarmkv *db, const char *key, size_t keylen, swarmkv_on_reply_callback_t *cb, void *cb_arg)
{
const char *argv[2];
size_t argv_len[2];
- argv[0]="smembers";
- argv_len[0]=strlen(argv[0]);
- argv[1]=key;
- argv_len[1]=keylen;
+ argv[0] = "smembers";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = key;
+ argv_len[1] = keylen;
swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2, argv, argv_len);
return;
}
-void swarmkv_scard(struct swarmkv *db, const char* key, size_t keylen, swarmkv_on_reply_callback_t *cb, void *cb_arg)
+void swarmkv_scard(struct swarmkv *db, const char *key, size_t keylen, swarmkv_on_reply_callback_t *cb, void *cb_arg)
{
const char *argv[2];
size_t argv_len[2];
- argv[0]="scard";
- argv_len[0]=strlen(argv[0]);
- argv[1]=key;
- argv_len[1]=keylen;
+ argv[0] = "scard";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = key;
+ argv_len[1] = keylen;
swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2, argv, argv_len);
return;
}
int swarmkv_hset_string(struct swarmkv *db,
- const char *key, size_t keylen, const char* member, size_t memberlen, const char *value, size_t vallen)
+ const char *key, size_t keylen, const char *member, size_t memberlen, const char *value, size_t vallen)
{
return 0;
-}
-void swarmkv_del(struct swarmkv * db, const char * key, size_t keylen, swarmkv_on_reply_callback_t *cb, void *cb_arg)
+}
+void swarmkv_del(struct swarmkv *db, const char *key, size_t keylen, swarmkv_on_reply_callback_t *cb, void *cb_arg)
{
const char *argv[2];
size_t argv_len[2];
- argv[0]="del";
- argv_len[0]=strlen(argv[0]);
- argv[1]=key;
- argv_len[1]=keylen;
+ argv[0] = "del";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = key;
+ argv_len[1] = keylen;
swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2, argv, argv_len);
return;
}
-void swarmkv_incrby(struct swarmkv * db, const char * key, size_t keylen, long long increment, swarmkv_on_reply_callback_t *cb, void *cb_arg)
+void swarmkv_incrby(struct swarmkv *db, const char *key, size_t keylen, long long increment, swarmkv_on_reply_callback_t *cb, void *cb_arg)
{
const char *argv[3];
size_t argv_len[3];
- argv[0]="incrby";
- argv_len[0]=strlen(argv[0]);
- argv[1]=key;
- argv_len[1]=keylen;
+ argv[0] = "incrby";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = key;
+ argv_len[1] = keylen;
char buffer[32];
sprintf(buffer, "%lld", increment);
- argv[2]=buffer;
- argv_len[2]=strlen(buffer);
+ argv[2] = buffer;
+ argv_len[2] = strlen(buffer);
swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 3, argv, argv_len);
return;
}
-void swarmkv_tconsume(struct swarmkv * db, const char * key, size_t keylen, long long tokens, swarmkv_on_reply_callback_t *cb, void *cb_arg)
+void swarmkv_tconsume(struct swarmkv *db, const char *key, size_t keylen, long long tokens, swarmkv_on_reply_callback_t *cb, void *cb_arg)
{
const char *argv[3];
size_t argv_len[3];
- argv[0]="tconsume";
- argv_len[0]=strlen(argv[0]);
- argv[1]=key;
- argv_len[1]=keylen;
+ argv[0] = "tconsume";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = key;
+ argv_len[1] = keylen;
char buffer[32];
sprintf(buffer, "%lld", tokens);
- argv[2]=buffer;
- argv_len[2]=strlen(buffer);
+ argv[2] = buffer;
+ argv_len[2] = strlen(buffer);
swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 3, argv, argv_len);
return;
}
-void swarmkv_ftconsume(struct swarmkv * db, const char * key, size_t keylen, const char * member, size_t member_len, long long weight, long long tokens, swarmkv_on_reply_callback_t *cb, void *cb_arg)
+void swarmkv_ftconsume(struct swarmkv *db, const char *key, size_t keylen, const char *member, size_t member_len, long long weight, long long tokens, swarmkv_on_reply_callback_t *cb, void *cb_arg)
{
const char *argv[5];
size_t argv_len[5];
- argv[0]="ftconsume";
- argv_len[0]=strlen(argv[0]);
- argv[1]=key;
- argv_len[1]=keylen;
- argv[2]=member;
- argv_len[2]=member_len;
+ argv[0] = "ftconsume";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = key;
+ argv_len[1] = keylen;
+ argv[2] = member;
+ argv_len[2] = member_len;
char buffer1[32];
sprintf(buffer1, "%lld", weight);
- argv[3]=buffer1;
- argv_len[3]=strlen(buffer1);
+ argv[3] = buffer1;
+ argv_len[3] = strlen(buffer1);
char buffer2[32];
sprintf(buffer2, "%lld", tokens);
- argv[4]=buffer2;
- argv_len[4]=strlen(buffer2);
+ argv[4] = buffer2;
+ argv_len[4] = strlen(buffer2);
swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 5, argv, argv_len);
return;
}
-void swarmkv_btconsume(struct swarmkv * db, const char * key, size_t keylen, const char * member, size_t member_len, long long tokens, swarmkv_on_reply_callback_t *cb, void *cb_arg)
+void swarmkv_btconsume(struct swarmkv *db, const char *key, size_t keylen, const char *member, size_t member_len, long long tokens, swarmkv_on_reply_callback_t *cb, void *cb_arg)
{
const char *argv[4];
size_t argv_len[4];
- argv[0]="btconsume";
- argv_len[0]=strlen(argv[0]);
- argv[1]=key;
- argv_len[1]=keylen;
- argv[2]=member;
- argv_len[2]=member_len;
+ argv[0] = "btconsume";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = key;
+ argv_len[1] = keylen;
+ argv[2] = member;
+ argv_len[2] = member_len;
char buffer[32];
sprintf(buffer, "%lld", tokens);
- argv[3]=buffer;
- argv_len[3]=strlen(buffer);
+ argv[3] = buffer;
+ argv_len[3] = strlen(buffer);
swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 4, argv, argv_len);
return;
}
-void swarmkv_bfadd(struct swarmkv * db, const char * key, size_t keylen, const char *items[], const size_t items_len[], size_t n_items, swarmkv_on_reply_callback_t *cb, void *cb_arg)
+void swarmkv_bfadd(struct swarmkv *db, const char *key, size_t keylen, const char *items[], const size_t items_len[], size_t n_items, swarmkv_on_reply_callback_t *cb, void *cb_arg)
{
- const char *argv[2+n_items];
- size_t argv_len[2+n_items];
- argv[0]="bfadd";
- argv_len[0]=strlen(argv[0]);
- argv[1]=key;
- argv_len[1]=keylen;
- for(size_t i=0; i<n_items; i++)
+ const char *argv[2 + n_items];
+ size_t argv_len[2 + n_items];
+ argv[0] = "bfadd";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = key;
+ argv_len[1] = keylen;
+ for (size_t i = 0; i < n_items; i++)
{
- argv[2+i]=items[i];
- argv_len[2+i]=items_len[i];
+ argv[2 + i] = items[i];
+ argv_len[2 + i] = items_len[i];
}
- swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2+n_items, argv, argv_len);
+ swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2 + n_items, argv, argv_len);
return;
}
-void swarmkv_bfmexists(struct swarmkv * db, const char * key, size_t keylen, const char *items[], const size_t items_len[], size_t n_items, swarmkv_on_reply_callback_t *cb, void *cb_arg)
+void swarmkv_bfmexists(struct swarmkv *db, const char *key, size_t keylen, const char *items[], const size_t items_len[], size_t n_items, swarmkv_on_reply_callback_t *cb, void *cb_arg)
{
- const char *argv[2+n_items];
- size_t argv_len[2+n_items];
- argv[0]="bfmexists";
- argv_len[0]=strlen(argv[0]);
- argv[1]=key;
- argv_len[1]=keylen;
- for(size_t i=0; i<n_items; i++)
+ const char *argv[2 + n_items];
+ size_t argv_len[2 + n_items];
+ argv[0] = "bfmexists";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = key;
+ argv_len[1] = keylen;
+ for (size_t i = 0; i < n_items; i++)
{
- argv[2+i]=items[i];
- argv_len[2+i]=items_len[i];
+ argv[2 + i] = items[i];
+ argv_len[2 + i] = items_len[i];
}
- swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2+n_items, argv, argv_len);
+ swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2 + n_items, argv, argv_len);
return;
}
-void swarmkv_cmsincrby(struct swarmkv * db, const char * key, size_t keylen, const char * items[], const size_t items_len[], long long increments[], size_t n_increment, swarmkv_on_reply_callback_t * cb, void * cb_arg)
+void swarmkv_cmsincrby(struct swarmkv *db, const char *key, size_t keylen, const char *items[], const size_t items_len[], long long increments[], size_t n_increment, swarmkv_on_reply_callback_t *cb, void *cb_arg)
{
- const char *argv[2+2*n_increment];
- size_t argv_len[2+2*n_increment];
+ const char *argv[2 + 2 * n_increment];
+ size_t argv_len[2 + 2 * n_increment];
char inc_buffer[n_increment][32];
- argv[0]="cmsincrby";
- argv_len[0]=strlen(argv[0]);
- argv[1]=key;
- argv_len[1]=keylen;
- for(size_t i=0; i<n_increment; i++)
+ argv[0] = "cmsincrby";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = key;
+ argv_len[1] = keylen;
+ for (size_t i = 0; i < n_increment; i++)
{
sprintf(inc_buffer[i], "%lld", increments[i]);
- argv[2+2*i]=items[i];
- argv_len[2+2*i]=items_len[i];
- argv[3+2*i]=inc_buffer[i];
- argv_len[3+2*i]=strlen(inc_buffer[i]);
+ argv[2 + 2 * i] = items[i];
+ argv_len[2 + 2 * i] = items_len[i];
+ argv[3 + 2 * i] = inc_buffer[i];
+ argv_len[3 + 2 * i] = strlen(inc_buffer[i]);
}
- swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2+2*n_increment, argv, argv_len);
+ swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2 + 2 * n_increment, argv, argv_len);
return;
}
-void swarmkv_cmsmquery(struct swarmkv * db, const char * key, size_t keylen, const char * items[], const size_t items_len[], size_t n_items, swarmkv_on_reply_callback_t * cb, void * cb_arg)
+void swarmkv_cmsmquery(struct swarmkv *db, const char *key, size_t keylen, const char *items[], const size_t items_len[], size_t n_items, swarmkv_on_reply_callback_t *cb, void *cb_arg)
{
- const char *argv[2+n_items];
- size_t argv_len[2+n_items];
- argv[0]="cmsmquery";
- argv_len[0]=strlen(argv[0]);
- argv[1]=key;
- argv_len[1]=keylen;
- for(size_t i=0; i<n_items; i++)
+ const char *argv[2 + n_items];
+ size_t argv_len[2 + n_items];
+ argv[0] = "cmsmquery";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = key;
+ argv_len[1] = keylen;
+ for (size_t i = 0; i < n_items; i++)
{
- argv[2+i]=items[i];
- argv_len[2+i]=items_len[i];
+ argv[2 + i] = items[i];
+ argv_len[2 + i] = items_len[i];
}
- swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2+n_items, argv, argv_len);
+ swarmkv_async_command_on_argv(db, cb, cb_arg, NULL, 2 + n_items, argv, argv_len);
return;
} \ No newline at end of file
diff --git a/src/swarmkv_cmd_spec.c b/src/swarmkv_cmd_spec.c
new file mode 100644
index 0000000..d7f6b54
--- /dev/null
+++ b/src/swarmkv_cmd_spec.c
@@ -0,0 +1,202 @@
+#include "swarmkv_cmd_spec.h"
+#include "swarmkv_utils.h"
+#include "uthash.h"
+
+#include <ctype.h> //isspace
+
+struct swarmkv_command_table
+{
+ struct swarmkv_module module;
+ struct swarmkv_cmd_spec *hash_table;
+};
+static struct swarmkv_command_table *module2command_table(const struct swarmkv_module *module)
+{
+ assert(0 == strcmp(module->name, "command_table"));
+ struct swarmkv_command_table *table = container_of(module, struct swarmkv_command_table, module);
+ assert(table == module->mod_ctx);
+ return table;
+}
+struct swarmkv_module * swarmkv_command_table_new(void)
+{
+ struct swarmkv_command_table *table=ALLOC(struct swarmkv_command_table, 1);
+ strncpy(table->module.name, "command_table", sizeof(table->module.name));
+ table->module.mod_ctx=table;
+ table->hash_table=NULL;
+ return &table->module;
+}
+void swarmkv_command_table_free(struct swarmkv_module *mod_table)
+{
+ struct swarmkv_command_table *table = module2command_table(mod_table);
+ struct swarmkv_cmd_spec *spec = NULL, *tmp_spec = NULL;
+
+ HASH_ITER(hh, table->hash_table, spec, tmp_spec)
+ {
+ HASH_DEL(table->hash_table, spec);
+ free(spec);
+ }
+ free(table);
+}
+
+
+void swarmkv_command_table_register(struct swarmkv_module *mod_table, const char *name, const char *hint,
+ int arity, int key_offset, enum cmd_key_flag flag, enum key_not_found_reply failover, int auto_route,
+ command_proc_func *proc, struct swarmkv_module *module)
+{
+ struct swarmkv_command_table *table = module2command_table(mod_table);
+ struct swarmkv_cmd_spec *spec = NULL;
+
+ spec = ALLOC(struct swarmkv_cmd_spec, 1);
+ spec->name = name;
+ spec->hint = hint;
+ spec->arity = arity;
+ spec->key_offset = key_offset;
+ spec->flag = flag;
+ spec->nokey_reply = failover;
+ spec->proc = proc;
+ spec->auto_route = auto_route;
+
+ spec->module = module;
+ HASH_ADD_KEYPTR(hh, table->hash_table, spec->name, strlen(spec->name), spec);
+ return;
+}
+const struct swarmkv_cmd_spec *swarmkv_command_table_get_spec_by_argv(const struct swarmkv_module *mod_table, size_t argc, char* const argv[])
+{
+ struct swarmkv_command_table *table = module2command_table(mod_table);
+ struct swarmkv_cmd_spec *spec=NULL;
+ char name[256]="";
+ strncpy(name, argv[0], sizeof(name));
+ toUpper(name);
+ HASH_FIND(hh, table->hash_table, name, strlen(name), spec);
+ if(spec)
+ {
+ return spec;
+ }
+ if(argc<2)
+ {
+ return NULL;
+ }
+ snprintf(name, sizeof(name), "%s %s", argv[0], argv[1]);
+ toUpper(name);
+ HASH_FIND(hh, table->hash_table, name, strlen(name), spec);
+ if(spec)
+ {
+ return spec;
+ }
+ return NULL;
+}
+size_t swarmkv_command_table_count(const struct swarmkv_module *mod_table)
+{
+ struct swarmkv_command_table *table = module2command_table(mod_table);
+ return HASH_COUNT(table->hash_table);
+}
+size_t swarmkv_command_table_list_names(const struct swarmkv_module *mod_table, const char* cmd_names[], size_t sz)
+{
+ struct swarmkv_command_table *table = module2command_table(mod_table);
+ struct swarmkv_cmd_spec *spec=NULL, *tmp_spec=NULL;
+ size_t i = 0, count = 0;
+ count = swarmkv_command_table_count(mod_table);
+ assert(sz >= count);
+
+ HASH_ITER(hh, table->hash_table, spec, tmp_spec)
+ {
+ cmd_names[i]=spec->name;
+ i++;
+ }
+ assert(i == count);
+ return i;
+}
+enum cmd_exec_result command_list_command(struct swarmkv_module *mod_command_table, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
+{
+ size_t cnt = swarmkv_command_table_count(mod_command_table);
+ const char *cmd_names[cnt];
+ swarmkv_command_table_list_names(mod_command_table, cmd_names, cnt);
+ *reply=swarmkv_reply_new_array(cnt);
+ for(int i=0; i<cnt; i++)
+ {
+ (*reply)->elements[i]=swarmkv_reply_new_string(cmd_names[i], strlen(cmd_names[i]));
+ }
+ return FINISHED;
+}
+size_t swarmkv_command_table_find_possible_names(const struct swarmkv_module *mod_table, const char *prefix, const char* cmd_names[], size_t sz)
+{
+ struct swarmkv_command_table *table = module2command_table(mod_table);
+ struct swarmkv_cmd_spec *spec=NULL, *tmp_spec=NULL;
+ size_t n_matched=0;
+ HASH_ITER(hh, table->hash_table, spec, tmp_spec)
+ {
+ if(0==strncasecmp(spec->name, prefix, strlen(prefix)) && n_matched<sz)
+ {
+ cmd_names[n_matched]=spec->name;
+ n_matched++;
+ }
+ }
+ return n_matched;
+}
+char *swarmkv_command_table_get_command_hint(const struct swarmkv_module *mod_table, const char *cmd_name)
+{
+
+ int argc, buflen = strlen(cmd_name);
+ sds *argv = sdssplitargs(cmd_name,&argc);
+ int endspace = buflen && isspace(cmd_name[buflen-1]);
+
+ if (argc == 0)
+ {
+ sdsfreesplitres(argv,argc);
+ return NULL;
+ }
+ struct swarmkv_command_table *table = module2command_table(mod_table);
+ size_t i;
+ struct swarmkv_cmd_spec *spec=NULL, *tmp_spec=NULL;
+ HASH_ITER(hh, table->hash_table, spec, tmp_spec)
+ {
+ int argc_spec;
+ sds *argv_spec = sdssplitargs(spec->name, &argc_spec);
+ sds params=sdsdup(argv[0]);
+ for(i=1; i<argc_spec && argc>=argc_spec; i++)
+ {
+ params = sdscatprintf(params, " %s", argv[i]);
+ }
+ sdsfreesplitres(argv_spec,argc_spec);
+
+ if(0==strcasecmp(spec->name, params))
+ {
+ sds hint = sdsnew(spec->hint);
+ int toremove = argc - argc_spec;
+ while(toremove > 0 && sdslen(hint)) {
+ if (hint[0] == '[') break;
+ if (hint[0] == ' ') toremove--;
+ sdsrange(hint,1,-1);
+ }
+
+ if (!endspace) {
+ sds newhint = sdsnewlen(" ",1);
+ newhint = sdscatsds(newhint,hint);
+ sdsfree(hint);
+ hint = newhint;
+ }
+ sdsfree(params);
+ sdsfreesplitres(argv,argc);
+ return hint;
+ }
+ sdsfree(params);
+ }
+ sdsfreesplitres(argv,argc);
+ return NULL;
+}
+int command_spec_is_sufficient_args(const struct swarmkv_cmd_spec *spec, const struct swarmkv_cmd *cmd)
+{
+ size_t expect_argc=0;
+ if(strchr(spec->name, ' '))
+ {
+ expect_argc=spec->arity+2;
+ }
+ else
+ {
+ expect_argc=spec->arity+1;
+ }
+ if(cmd->argc<expect_argc)
+ {
+ return 0;
+ }
+ return 1;
+} \ No newline at end of file
diff --git a/src/swarmkv_cmd_spec.h b/src/swarmkv_cmd_spec.h
index 8e5e10c..9abc70d 100644
--- a/src/swarmkv_cmd_spec.h
+++ b/src/swarmkv_cmd_spec.h
@@ -67,5 +67,17 @@ struct swarmkv_cmd_spec
struct swarmkv_module *module;
UT_hash_handle hh;
};
+int command_spec_is_sufficient_args(const struct swarmkv_cmd_spec *spec, const struct swarmkv_cmd *cmd);
+struct swarmkv_module *swarmkv_command_table_new();
+void swarmkv_command_table_free(struct swarmkv_module *table);
+void swarmkv_command_table_register(struct swarmkv_module *table, const char *name, const char *hint,
+ int arity, int key_offset, enum cmd_key_flag flag, enum key_not_found_reply failover, int auto_route,
+ command_proc_func *proc, struct swarmkv_module *module);
+const struct swarmkv_cmd_spec *swarmkv_command_table_get_spec_by_argv(const struct swarmkv_module *table, size_t argc, char* const argv[]);
-
+size_t swarmkv_command_table_find_possible_names(const struct swarmkv_module *mod_table, const char *prefix, const char* cmd_names[], size_t sz);
+char *swarmkv_command_table_get_command_hint(const struct swarmkv_module *mod_table, const char *cmd_name);
+size_t swarmkv_command_table_count(const struct swarmkv_module *mod_table);
+size_t swarmkv_command_table_list_names(const struct swarmkv_module *mod_table, const char* cmd_names[], size_t sz);
+size_t swarmkv_command_table_count(const struct swarmkv_module *mod_table);
+enum cmd_exec_result command_list_command(struct swarmkv_module *mod_command_table, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply); \ No newline at end of file
diff --git a/src/swarmkv_common.c b/src/swarmkv_common.c
index d915b8a..ec492f8 100644
--- a/src/swarmkv_common.c
+++ b/src/swarmkv_common.c
@@ -13,11 +13,11 @@
int str2integer(const char *str, long long *integer)
{
- char *endptr=NULL;
- *integer=strtol(str, &endptr, 10);
- if(*endptr!='\0')
+ char *endptr = NULL;
+ *integer = strtol(str, &endptr, 10);
+ if (*endptr != '\0')
{
- return -1;
+ return -1;
}
return 0;
}
@@ -58,118 +58,126 @@ void swarmkv_reply_print(const struct swarmkv_reply *reply, FILE* stream)
}
}*/
-sds swarmkv_reply_format(const struct swarmkv_reply *r, char *prefix) {
- sds out = sdsempty();
- switch (r->type) {
- case SWARMKV_REPLY_ERROR:
- out = sdscatprintf(out,"(error) %s\n", r->str);
+sds swarmkv_reply_format(const struct swarmkv_reply *r, char *prefix)
+{
+ sds out = sdsempty();
+ switch (r->type)
+ {
+ case SWARMKV_REPLY_ERROR:
+ out = sdscatprintf(out, "(error) %s\n", r->str);
+ break;
+ case SWARMKV_REPLY_STATUS:
+ out = sdscat(out, r->str);
+ out = sdscat(out, "\n");
+ break;
+ case SWARMKV_REPLY_INTEGER:
+ out = sdscatprintf(out, "(integer) %lld\n", r->integer);
break;
- case SWARMKV_REPLY_STATUS:
- out = sdscat(out, r->str);
- out = sdscat(out, "\n");
- break;
- case SWARMKV_REPLY_INTEGER:
- out = sdscatprintf(out,"(integer) %lld\n", r->integer);
- break;
case SWARMKV_REPLY_DOUBLE:
- out = sdscatprintf(out,"(double) %f\n", r->dval);
+ out = sdscatprintf(out, "(double) %f\n", r->dval);
break;
- case SWARMKV_REPLY_STRING:
- case SWARMKV_REPLY_VERBATIM:
+ case SWARMKV_REPLY_STRING:
+ case SWARMKV_REPLY_VERBATIM:
case SWARMKV_REPLY_NODE:
- /* If you are producing output for the standard output we want
- * a more interesting output with quoted characters and so forth,
- * unless it's a verbatim string type. */
- if (r->type == SWARMKV_REPLY_STRING) {
- out = sdscatrepr(out, r->str, r->len);
- out = sdscat(out, "\n");
- } else {
- out = sdscatlen(out, r->str, r->len);
- out = sdscat(out, "\n");
- }
- break;
- case SWARMKV_REPLY_NIL:
+ /* If you are producing output for the standard output we want
+ * a more interesting output with quoted characters and so forth,
+ * unless it's a verbatim string type. */
+ if (r->type == SWARMKV_REPLY_STRING)
+ {
+ out = sdscatrepr(out, r->str, r->len);
+ out = sdscat(out, "\n");
+ }
+ else
+ {
+ out = sdscatlen(out, r->str, r->len);
+ out = sdscat(out, "\n");
+ }
+ break;
+ case SWARMKV_REPLY_NIL:
out = sdscat(out, "(nil)\n");
break;
- case SWARMKV_REPLY_ARRAY:
- if (r->n_element == 0)
+ case SWARMKV_REPLY_ARRAY:
+ if (r->n_element == 0)
{
- out = sdscat(out,"(empty array)\n");
- }
+ out = sdscat(out, "(empty array)\n");
+ }
else
{
- unsigned int i, idxlen = 0;
- char _prefixlen[16];
- char _prefixfmt[16];
- sds _prefix;
- sds tmp;
+ unsigned int i, idxlen = 0;
+ char _prefixlen[16];
+ char _prefixfmt[16];
+ sds _prefix;
+ sds tmp;
- /* Calculate chars needed to represent the largest index */
- i = r->n_element;
- do
+ /* Calculate chars needed to represent the largest index */
+ i = r->n_element;
+ do
{
- idxlen++;
- i /= 10;
- } while(i);
+ idxlen++;
+ i /= 10;
+ } while (i);
- /* Prefix for nested multi bulks should grow with idxlen+2 spaces */
- memset(_prefixlen,' ', idxlen+2);
- _prefixlen[idxlen+2] = '\0';
- _prefix = sdscat(sdsnew(prefix), _prefixlen);
+ /* Prefix for nested multi bulks should grow with idxlen+2 spaces */
+ memset(_prefixlen, ' ', idxlen + 2);
+ _prefixlen[idxlen + 2] = '\0';
+ _prefix = sdscat(sdsnew(prefix), _prefixlen);
- /* Setup prefix format for every entry */
- char numsep = ')';
- snprintf(_prefixfmt,sizeof(_prefixfmt), "%%s%%%ud%c ", idxlen, numsep);
+ /* Setup prefix format for every entry */
+ char numsep = ')';
+ snprintf(_prefixfmt, sizeof(_prefixfmt), "%%s%%%ud%c ", idxlen, numsep);
- for (i = 0; i < r->n_element; i++)
+ for (i = 0; i < r->n_element; i++)
{
- unsigned int human_idx = i;
- human_idx++; /* Make it 1-based. */
+ unsigned int human_idx = i;
+ human_idx++; /* Make it 1-based. */
- /* Don't use the prefix for the first element, as the parent
- * caller already prepended the index number. */
- out = sdscatprintf(out, _prefixfmt, i == 0 ? "" : prefix, human_idx);
+ /* Don't use the prefix for the first element, as the parent
+ * caller already prepended the index number. */
+ out = sdscatprintf(out, _prefixfmt, i == 0 ? "" : prefix, human_idx);
- /* Format the multi bulk entry */
- tmp = swarmkv_reply_format(r->elements[i], _prefix);
- out = sdscatlen(out, tmp, sdslen(tmp));
- sdsfree(tmp);
- }
- sdsfree(_prefix);
- }
+ /* Format the multi bulk entry */
+ tmp = swarmkv_reply_format(r->elements[i], _prefix);
+ out = sdscatlen(out, tmp, sdslen(tmp));
+ sdsfree(tmp);
+ }
+ sdsfree(_prefix);
+ }
break;
- default:
- sdscatprintf(out,"Unknown reply type: %d\n", r->type);
- break;
- }
- return out;
+ default:
+ sdscatprintf(out, "Unknown reply type: %d\n", r->type);
+ break;
+ }
+ return out;
}
-void swarmkv_reply_print(const struct swarmkv_reply *reply, FILE* stream)
+void swarmkv_reply_print(const struct swarmkv_reply *reply, FILE *stream)
{
- sds formated=swarmkv_reply_format(reply, "");
+ sds formated = swarmkv_reply_format(reply, "");
fwrite(formated, sdslen(formated), 1, stream);
sdsfree(formated);
return;
}
-struct swarmkv_reply *swarmkv_reply_new_string(const char* str, size_t sz)
+struct swarmkv_reply *swarmkv_reply_new_string(const char *str, size_t sz)
{
- struct swarmkv_reply *reply=ALLOC(struct swarmkv_reply, 1);
- reply->type=SWARMKV_REPLY_STRING;
- reply->len=sz;
- reply->str=sdsnewlen(str, sz);
+ struct swarmkv_reply *reply = ALLOC(struct swarmkv_reply, 1);
+ reply->type = SWARMKV_REPLY_STRING;
+ reply->len = sz;
+ reply->str = sdsnewlen(str, sz);
return reply;
}
struct swarmkv_reply *swarmkv_reply_new_verbatim(const char *str, size_t sz, const char *ext)
{
- struct swarmkv_reply *reply=ALLOC(struct swarmkv_reply, 1);
- reply->type=SWARMKV_REPLY_VERBATIM;
- reply->len=sz;
- reply->str=sdsnewlen(str, sz);
+ struct swarmkv_reply *reply = ALLOC(struct swarmkv_reply, 1);
+ reply->type = SWARMKV_REPLY_VERBATIM;
+ reply->len = sz;
+ reply->str = sdsnewlen(str, sz);
for (int i = 0; i < 3; i++)
{
- if (*ext == '\0') {
+ if (*ext == '\0')
+ {
reply->vtype[i] = ' ';
- } else {
+ }
+ else
+ {
reply->vtype[i] = *ext++;
}
}
@@ -178,101 +186,99 @@ struct swarmkv_reply *swarmkv_reply_new_verbatim(const char *str, size_t sz, con
struct swarmkv_reply *swarmkv_reply_new_string_from_integer(long long integer)
{
- struct swarmkv_reply *reply=ALLOC(struct swarmkv_reply, 1);
- reply->type=SWARMKV_REPLY_STRING;
- reply->str=sdsfromlonglong(integer);
- reply->len=sdslen(reply->str);
+ struct swarmkv_reply *reply = ALLOC(struct swarmkv_reply, 1);
+ reply->type = SWARMKV_REPLY_STRING;
+ reply->str = sdsfromlonglong(integer);
+ reply->len = sdslen(reply->str);
return reply;
}
struct swarmkv_reply *swarmkv_reply_new_string_fmt(const char *fmt, ...)
{
- struct swarmkv_reply *reply=ALLOC(struct swarmkv_reply, 1);
- reply->type=SWARMKV_REPLY_STRING;
+ struct swarmkv_reply *reply = ALLOC(struct swarmkv_reply, 1);
+ reply->type = SWARMKV_REPLY_STRING;
va_list ap;
- va_start(ap, fmt);
- reply->str=sdscatvprintf(sdsempty(), fmt, ap);
- va_end(ap);
- reply->len=sdslen(reply->str);
+ va_start(ap, fmt);
+ reply->str = sdscatvprintf(sdsempty(), fmt, ap);
+ va_end(ap);
+ reply->len = sdslen(reply->str);
return reply;
-
}
struct swarmkv_reply *swarmkv_reply_new_array(size_t n_element)
{
- struct swarmkv_reply *reply=ALLOC(struct swarmkv_reply, 1);
- reply->type=SWARMKV_REPLY_ARRAY;
- reply->n_element=n_element;
- reply->elements=ALLOC(struct swarmkv_reply*, n_element);
+ struct swarmkv_reply *reply = ALLOC(struct swarmkv_reply, 1);
+ reply->type = SWARMKV_REPLY_ARRAY;
+ reply->n_element = n_element;
+ reply->elements = ALLOC(struct swarmkv_reply *, n_element);
return reply;
-
}
struct swarmkv_reply *swarmkv_reply_new_integer(long long integer)
{
- struct swarmkv_reply *reply=ALLOC(struct swarmkv_reply, 1);
- reply->type=SWARMKV_REPLY_INTEGER;
- reply->integer=integer;
+ struct swarmkv_reply *reply = ALLOC(struct swarmkv_reply, 1);
+ reply->type = SWARMKV_REPLY_INTEGER;
+ reply->integer = integer;
return reply;
}
struct swarmkv_reply *swarmkv_reply_new_double(double dval)
{
- struct swarmkv_reply *reply=ALLOC(struct swarmkv_reply, 1);
- reply->type=SWARMKV_REPLY_DOUBLE;
- reply->dval=dval;
+ struct swarmkv_reply *reply = ALLOC(struct swarmkv_reply, 1);
+ reply->type = SWARMKV_REPLY_DOUBLE;
+ reply->dval = dval;
return reply;
}
struct swarmkv_reply *swarmkv_reply_new_nil(void)
{
- struct swarmkv_reply *reply=ALLOC(struct swarmkv_reply, 1);
- reply->type=SWARMKV_REPLY_NIL;
+ struct swarmkv_reply *reply = ALLOC(struct swarmkv_reply, 1);
+ reply->type = SWARMKV_REPLY_NIL;
return reply;
}
struct swarmkv_reply *swarmkv_reply_new_status(const char *format, ...)
{
- struct swarmkv_reply *reply=ALLOC(struct swarmkv_reply, 1);
- reply->type=SWARMKV_REPLY_STATUS;
+ struct swarmkv_reply *reply = ALLOC(struct swarmkv_reply, 1);
+ reply->type = SWARMKV_REPLY_STATUS;
va_list ap;
- va_start(ap, format);
- reply->str=sdscatvprintf(sdsempty(), format, ap);
- va_end(ap);
- reply->len=strlen(reply->str);
+ va_start(ap, format);
+ reply->str = sdscatvprintf(sdsempty(), format, ap);
+ va_end(ap);
+ reply->len = strlen(reply->str);
return reply;
}
struct swarmkv_reply *swarmkv_reply_new_error(const char *format, ...)
{
- struct swarmkv_reply *reply=ALLOC(struct swarmkv_reply, 1);
- reply->type=SWARMKV_REPLY_ERROR;
+ struct swarmkv_reply *reply = ALLOC(struct swarmkv_reply, 1);
+ reply->type = SWARMKV_REPLY_ERROR;
va_list ap;
- va_start(ap, format);
- reply->str=sdscatvprintf(sdsempty(), format, ap);
- va_end(ap);
- reply->len=strlen(reply->str);
+ va_start(ap, format);
+ reply->str = sdscatvprintf(sdsempty(), format, ap);
+ va_end(ap);
+ reply->len = strlen(reply->str);
return reply;
}
struct swarmkv_reply *swarmkv_reply_new_node(node_t *node, int is_ask)
{
- struct swarmkv_reply *reply=ALLOC(struct swarmkv_reply, 1);
- reply->type=SWARMKV_REPLY_NODE;
- if(is_ask)
+ struct swarmkv_reply *reply = ALLOC(struct swarmkv_reply, 1);
+ reply->type = SWARMKV_REPLY_NODE;
+ if (is_ask)
{
- reply->str=sdscatfmt(sdsempty(), "-ASK %s", node->addr);
+ reply->str = sdscatfmt(sdsempty(), "-ASK %s", node->addr);
}
else
{
- reply->str=sdscatfmt(sdsempty(), "%s", node->addr);
+ reply->str = sdscatfmt(sdsempty(), "%s", node->addr);
}
- reply->len=strlen(reply->str);
+ reply->len = strlen(reply->str);
return reply;
}
int node_sanity(const node_t *node)
{
return 1;
- char c=0;
- for(size_t i=0; i<sizeof(node->addr); i++)
- {
- c=node->addr[i];
- if((c>='0'&&c<='9') ||
- c=='.' ||
- c==':'||
- c==0)
+ char c = 0;
+ for (size_t i = 0; i < sizeof(node->addr); i++)
+ {
+ c = node->addr[i];
+ if ((c >= '0' && c <= '9') ||
+ c == '.' ||
+ c == ':' ||
+ c == 0)
{
continue;
}
@@ -307,9 +313,9 @@ int node_compare(const node_t *node1, const node_t *node2)
}
int node_list_exists(const node_t *list, size_t n_list, const node_t *addr)
{
- for(size_t i=0; i<n_list; i++)
+ for (size_t i = 0; i < n_list; i++)
{
- if(0==node_compare(list+i, addr))
+ if (0 == node_compare(list + i, addr))
{
return 1;
}
@@ -318,14 +324,14 @@ int node_list_exists(const node_t *list, size_t n_list, const node_t *addr)
}
int node_list_remove(node_t *list, size_t n_list, const node_t *addr)
{
- int removed=0;
+ int removed = 0;
node_t copy[n_list];
- memcpy(copy, list, sizeof(node_t)*n_list);
- for(size_t i=0, j=0; i<n_list; i++)
+ memcpy(copy, list, sizeof(node_t) * n_list);
+ for (size_t i = 0, j = 0; i < n_list; i++)
{
- if(0!=node_compare(copy+i, addr))
+ if (0 != node_compare(copy + i, addr))
{
- memcpy(list+j, copy+i, sizeof(node_t));
+ memcpy(list + j, copy + i, sizeof(node_t));
j++;
}
else
@@ -337,14 +343,14 @@ int node_list_remove(node_t *list, size_t n_list, const node_t *addr)
}
void node_copy(node_t *dst, const node_t *src)
{
- memset(dst, 0, sizeof(node_t));
+ memset(dst, 0, sizeof(node_t));
assert(node_sanity(src));
- memcpy(dst, src, sizeof(node_t));
+ memcpy(dst, src, sizeof(node_t));
return;
}
int node_is_empty(const node_t *node)
{
- return ((node==NULL)||(node->addr[0]==0));
+ return ((node == NULL) || (node->addr[0] == 0));
}
void node_init(node_t *node, const char *ipv4, unsigned int port)
{
@@ -355,7 +361,7 @@ void node_init(node_t *node, const char *ipv4, unsigned int port)
void node_init_from_cstr(node_t *node, const char *addr_str)
{
memset(node, 0, sizeof(node_t));
- assert(strlen(addr_str)<sizeof(node_t));
+ assert(strlen(addr_str) < sizeof(node_t));
assert(strchr(addr_str, ':'));
strncpy(node->addr, addr_str, sizeof(node->addr));
return;
@@ -363,266 +369,267 @@ void node_init_from_cstr(node_t *node, const char *addr_str)
void node_init_from_string(node_t *node, const char *addr_str, size_t sz_addr)
{
memset(node, 0, sizeof(node_t));
- assert(sz_addr<=sizeof(node->addr));
+ assert(sz_addr <= sizeof(node->addr));
strncpy(node->addr, addr_str, sz_addr);
return;
}
int node_init_from_reply(node_t *node, const struct swarmkv_reply *reply)
{
- if(reply->type!=SWARMKV_REPLY_NODE)
+ if (reply->type != SWARMKV_REPLY_NODE)
{
return -1;
}
memset(node, 0, sizeof(node_t));
- const char *p=reply->str;
- if(0==strncasecmp(reply->str, "-ASK ", 5))
+ const char *p = reply->str;
+ if (0 == strncasecmp(reply->str, "-ASK ", 5))
{
- p+=5;
+ p += 5;
}
node_init_from_cstr(node, p);
return 0;
}
int node_list_new_from_reply(node_t **node_list, size_t *n_node, const struct swarmkv_reply *reply)
{
- if(reply->type==SWARMKV_REPLY_NIL)
+ if (reply->type == SWARMKV_REPLY_NIL)
{
- *n_node=0;
+ *n_node = 0;
return 0;
}
- if(reply->type!=SWARMKV_REPLY_ARRAY)
+ if (reply->type != SWARMKV_REPLY_ARRAY)
{
return -1;
}
- *n_node=reply->n_element;
- *node_list=ALLOC(node_t, *n_node);
- for(size_t i=0; i<*n_node; i++)
+ *n_node = reply->n_element;
+ *node_list = ALLOC(node_t, *n_node);
+ for (size_t i = 0; i < *n_node; i++)
{
- node_init_from_reply(*node_list+i, reply->elements[i]);
+ node_init_from_reply(*node_list + i, reply->elements[i]);
}
return 0;
}
int node_parse(const node_t *node, unsigned int *port, char *addr_str, size_t sz_addr)
{
- int n_read=0;
- n_read=sscanf(node->addr, "%[^:]:%u", addr_str, port);
- return n_read==2?0:-1;
-}
-void node_init_from_sockaddr(node_t *node, const struct sockaddr * sa)
-{
- char ip[MAX_IPV4_ADDR_LEN+1];
- size_t ip_len=sizeof(ip);
- unsigned int port=0;
- switch(sa->sa_family)
- {
- case AF_INET:
- inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr),
- ip, ip_len);
- port=htons(((struct sockaddr_in *)sa)->sin_port);
- break;
- case AF_INET6:
- inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr),
- ip, ip_len);
- port=htons(((struct sockaddr_in6 *)sa)->sin6_port);
- assert(0);//node_t cann't hold IPv6 yet.
- break;
- default:
- assert(0);
- break;;
- }
+ int n_read = 0;
+ n_read = sscanf(node->addr, "%[^:]:%u", addr_str, port);
+ return n_read == 2 ? 0 : -1;
+}
+void node_init_from_sockaddr(node_t *node, const struct sockaddr *sa)
+{
+ char ip[MAX_IPV4_ADDR_LEN + 1];
+ size_t ip_len = sizeof(ip);
+ unsigned int port = 0;
+ switch (sa->sa_family)
+ {
+ case AF_INET:
+ inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr),
+ ip, ip_len);
+ port = htons(((struct sockaddr_in *)sa)->sin_port);
+ break;
+ case AF_INET6:
+ inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr),
+ ip, ip_len);
+ port = htons(((struct sockaddr_in6 *)sa)->sin6_port);
+ assert(0); // node_t cann't hold IPv6 yet.
+ break;
+ default:
+ assert(0);
+ break;
+ ;
+ }
memset(node, 0, sizeof(node_t));
snprintf(node->addr, sizeof(node->addr), "%s:%u", ip, port);
return;
}
void node_to_sockaddr(const node_t *node, struct sockaddr *sockaddr)
{
- struct sockaddr_in *sa4=(struct sockaddr_in *) sockaddr;
- struct sockaddr_in6 *sa6=(struct sockaddr_in6*) sockaddr;
- char ip[16]={};
- unsigned int port=0;
+ struct sockaddr_in *sa4 = (struct sockaddr_in *)sockaddr;
+ struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sockaddr;
+ char ip[16] = {};
+ unsigned int port = 0;
memset(sockaddr, 0, sizeof(struct sockaddr));
node_parse(node, &port, ip, sizeof(ip));
- if(NULL==strstr(ip, ":"))//ipv4
- {
+ if (NULL == strstr(ip, ":")) // ipv4
+ {
sa4->sin_family = AF_INET;
sa4->sin_addr.s_addr = inet_addr(ip);
sa4->sin_port = htons(port);
}
- else//ipv6
+ else // ipv6
{
sa6->sin6_family = AF_INET6;
- inet_pton(AF_INET6, ip, &sa6->sin6_addr);
- sa6->sin6_port = htons(port);
+ inet_pton(AF_INET6, ip, &sa6->sin6_addr);
+ sa6->sin6_port = htons(port);
}
}
struct swarmkv_reply *swarmkv_reply_dup(const struct swarmkv_reply *origin)
{
- struct swarmkv_reply *copy=ALLOC(struct swarmkv_reply, 1);
- copy->type=origin->type;
- size_t i=0;
+ struct swarmkv_reply *copy = ALLOC(struct swarmkv_reply, 1);
+ copy->type = origin->type;
+ size_t i = 0;
switch (origin->type)
{
- case SWARMKV_REPLY_INTEGER:
- copy->integer=origin->integer;
- break;
- case SWARMKV_REPLY_DOUBLE:
- copy->dval=origin->dval;
- break;
- case SWARMKV_REPLY_STRING:
- case SWARMKV_REPLY_STATUS:
- case SWARMKV_REPLY_ERROR:
- case SWARMKV_REPLY_NODE:
- case SWARMKV_REPLY_VERBATIM:
- copy->len=origin->len;
- copy->str=sdsdup(origin->str);
- if(origin->type==SWARMKV_REPLY_VERBATIM) memcpy(copy->vtype, origin->vtype, 4);
- break;
- case SWARMKV_REPLY_ARRAY:
- copy->n_element=origin->n_element;
- copy->elements=ALLOC(struct swarmkv_reply*, origin->n_element);
- for(i=0; i<origin->n_element; i++)
- {
- copy->elements[i]=swarmkv_reply_dup(origin->elements[i]);
- }
- break;
- default:
- break;
-
+ case SWARMKV_REPLY_INTEGER:
+ copy->integer = origin->integer;
+ break;
+ case SWARMKV_REPLY_DOUBLE:
+ copy->dval = origin->dval;
+ break;
+ case SWARMKV_REPLY_STRING:
+ case SWARMKV_REPLY_STATUS:
+ case SWARMKV_REPLY_ERROR:
+ case SWARMKV_REPLY_NODE:
+ case SWARMKV_REPLY_VERBATIM:
+ copy->len = origin->len;
+ copy->str = sdsdup(origin->str);
+ if (origin->type == SWARMKV_REPLY_VERBATIM)
+ memcpy(copy->vtype, origin->vtype, 4);
+ break;
+ case SWARMKV_REPLY_ARRAY:
+ copy->n_element = origin->n_element;
+ copy->elements = ALLOC(struct swarmkv_reply *, origin->n_element);
+ for (i = 0; i < origin->n_element; i++)
+ {
+ copy->elements[i] = swarmkv_reply_dup(origin->elements[i]);
+ }
+ break;
+ default:
+ break;
}
return copy;
}
void swarmkv_reply_merge_array(struct swarmkv_reply **dst, struct swarmkv_reply *src)
{
- if(src->type==SWARMKV_REPLY_NIL)
+ if (src->type == SWARMKV_REPLY_NIL)
{
swarmkv_reply_free(src);
return;
}
- if(*dst==NULL)
+ if (*dst == NULL)
{
- *dst=swarmkv_reply_new_array(0);
+ *dst = swarmkv_reply_new_array(0);
}
- if((*dst)->type!=SWARMKV_REPLY_ARRAY)
+ if ((*dst)->type != SWARMKV_REPLY_ARRAY)
{
return;
}
- if(src->type!=SWARMKV_REPLY_ARRAY)
+ if (src->type != SWARMKV_REPLY_ARRAY)
{
- (*dst)->elements=(struct swarmkv_reply **)realloc((*dst)->elements, ((*dst)->n_element+1)*sizeof(struct swarmkv_reply*));
- (*dst)->elements[(*dst)->n_element]=src;
- (*dst)->n_element+=1;
+ (*dst)->elements = (struct swarmkv_reply **)realloc((*dst)->elements, ((*dst)->n_element + 1) * sizeof(struct swarmkv_reply *));
+ (*dst)->elements[(*dst)->n_element] = src;
+ (*dst)->n_element += 1;
return;
}
- (*dst)->elements=(struct swarmkv_reply **)realloc((*dst)->elements, ((*dst)->n_element+src->n_element)*sizeof(struct swarmkv_reply*));
- size_t i=0;
- for(i=0; i<src->n_element; i++)
+ (*dst)->elements = (struct swarmkv_reply **)realloc((*dst)->elements, ((*dst)->n_element + src->n_element) * sizeof(struct swarmkv_reply *));
+ size_t i = 0;
+ for (i = 0; i < src->n_element; i++)
{
- (*dst)->elements[(*dst)->n_element+i]=src->elements[i];
- src->elements[i]=NULL;
+ (*dst)->elements[(*dst)->n_element + i] = src->elements[i];
+ src->elements[i] = NULL;
}
- (*dst)->n_element+=src->n_element;
- src->n_element=0;//Only free the parent strutcture.
+ (*dst)->n_element += src->n_element;
+ src->n_element = 0; // Only free the parent strutcture.
swarmkv_reply_free(src);
return;
}
void swarmkv_reply_append_string(struct swarmkv_reply **dst, struct swarmkv_reply *src)
{
- if(src->type==SWARMKV_REPLY_NIL) return;
- if(*dst==NULL)
+ if (src->type == SWARMKV_REPLY_NIL)
+ return;
+ if (*dst == NULL)
{
- *dst=swarmkv_reply_new_array(0);
+ *dst = swarmkv_reply_new_array(0);
}
- if((*dst)->type!=SWARMKV_REPLY_ARRAY || src->type!=SWARMKV_REPLY_STRING)
+ if ((*dst)->type != SWARMKV_REPLY_ARRAY || src->type != SWARMKV_REPLY_STRING)
{
return;
}
- (*dst)->elements=(struct swarmkv_reply **)realloc((*dst)->elements, ((*dst)->n_element+1)*sizeof(struct swarmkv_reply*));
- (*dst)->elements[(*dst)->n_element]=src;
- (*dst)->n_element+=1;
+ (*dst)->elements = (struct swarmkv_reply **)realloc((*dst)->elements, ((*dst)->n_element + 1) * sizeof(struct swarmkv_reply *));
+ (*dst)->elements[(*dst)->n_element] = src;
+ (*dst)->n_element += 1;
return;
}
void swarmkv_reply_free(struct swarmkv_reply *reply)
{
- size_t i=0;
+ size_t i = 0;
switch (reply->type)
{
- case SWARMKV_REPLY_STRING:
- case SWARMKV_REPLY_STATUS:
- case SWARMKV_REPLY_ERROR:
- case SWARMKV_REPLY_NODE:
- case SWARMKV_REPLY_VERBATIM:
- sdsfree(reply->str);
- reply->str=NULL;
- break;
- case SWARMKV_REPLY_ARRAY:
- for(i=0; i<reply->n_element; i++)
- {
- swarmkv_reply_free(reply->elements[i]);
- reply->elements[i]=NULL;
- }
- free(reply->elements);
- break;
- default:
- break;
+ case SWARMKV_REPLY_STRING:
+ case SWARMKV_REPLY_STATUS:
+ case SWARMKV_REPLY_ERROR:
+ case SWARMKV_REPLY_NODE:
+ case SWARMKV_REPLY_VERBATIM:
+ sdsfree(reply->str);
+ reply->str = NULL;
+ break;
+ case SWARMKV_REPLY_ARRAY:
+ for (i = 0; i < reply->n_element; i++)
+ {
+ swarmkv_reply_free(reply->elements[i]);
+ reply->elements[i] = NULL;
+ }
+ free(reply->elements);
+ break;
+ default:
+ break;
}
free(reply);
}
struct swarmkv_cmd *swarmkv_cmd_new(size_t argc, const node_t *caller)
{
- size_t size=sizeof(struct swarmkv_cmd)+argc*sizeof(sds);
- struct swarmkv_cmd *cmd=(struct swarmkv_cmd*)malloc(size);
+ size_t size = sizeof(struct swarmkv_cmd) + argc * sizeof(sds);
+ struct swarmkv_cmd *cmd = (struct swarmkv_cmd *)malloc(size);
node_copy(&cmd->caller, caller);
- cmd->argc=argc;
- cmd->argv=(sds*)((char*)cmd+sizeof(struct swarmkv_cmd));
+ cmd->argc = argc;
+ cmd->argv = (sds *)((char *)cmd + sizeof(struct swarmkv_cmd));
return cmd;
}
void swarmkv_cmd_free(struct swarmkv_cmd *p)
{
- size_t i=0;
- for(i=0; i<p->argc; i++)
+ size_t i = 0;
+ for (i = 0; i < p->argc; i++)
{
sdsfree(p->argv[i]);
- p->argv[i]=NULL;
+ p->argv[i] = NULL;
}
- p->argv=NULL;
+ p->argv = NULL;
free(p);
}
-struct swarmkv_cmd* swarmkv_cmd_dup(const struct swarmkv_cmd *origin)
+struct swarmkv_cmd *swarmkv_cmd_dup(const struct swarmkv_cmd *origin)
{
- struct swarmkv_cmd* copy=swarmkv_cmd_new(origin->argc, &origin->caller);
- size_t i=0;
- for(i=0; i<origin->argc; i++)
+ struct swarmkv_cmd *copy = swarmkv_cmd_new(origin->argc, &origin->caller);
+ size_t i = 0;
+ for (i = 0; i < origin->argc; i++)
{
- copy->argv[i]=sdsdup(origin->argv[i]);
+ copy->argv[i] = sdsdup(origin->argv[i]);
}
return copy;
}
sds keyslots2json(void *slot_container_base, size_t sz_slot_container, size_t offset_slot, size_t n_slot_container)
{
- cJSON *slot_array=cJSON_CreateArray();
- cJSON *slot=NULL;
- char range[256]="";
- size_t i=0;
- sds json_sds=NULL;
- assert(KEYSPACE_SLOT_NUM==n_slot_container);
- assert(sz_slot_container>=sizeof(struct key_slot));
- struct key_slot *iterator=(struct key_slot *)(slot_container_base+offset_slot);
- struct key_slot *start_slot=NULL, *end_slot=NULL;
- start_slot=end_slot=iterator;
- for(i=0; i<n_slot_container+1; i++)
- {
- iterator=(struct key_slot *)(slot_container_base+sz_slot_container*i+offset_slot);
- if(i<n_slot_container
- && 0==node_compare(&(iterator->owner), &(end_slot->owner)))
+ cJSON *slot_array = cJSON_CreateArray();
+ cJSON *slot = NULL;
+ char range[256] = "";
+ size_t i = 0;
+ sds json_sds = NULL;
+ assert(KEYSPACE_SLOT_NUM == n_slot_container);
+ assert(sz_slot_container >= sizeof(struct key_slot));
+ struct key_slot *iterator = (struct key_slot *)(slot_container_base + offset_slot);
+ struct key_slot *start_slot = NULL, *end_slot = NULL;
+ start_slot = end_slot = iterator;
+ for (i = 0; i < n_slot_container + 1; i++)
+ {
+ iterator = (struct key_slot *)(slot_container_base + sz_slot_container * i + offset_slot);
+ if (i < n_slot_container && 0 == node_compare(&(iterator->owner), &(end_slot->owner)))
{
- end_slot=iterator;
+ end_slot = iterator;
continue;
- }
- slot=cJSON_CreateObject();
- if(start_slot==end_slot)
+ }
+ slot = cJSON_CreateObject();
+ if (start_slot == end_slot)
{
snprintf(range, sizeof(range), "%d", start_slot->slot_id);
}
@@ -633,200 +640,205 @@ sds keyslots2json(void *slot_container_base, size_t sz_slot_container, size_t of
cJSON_AddStringToObject(slot, "slot", range);
cJSON_AddStringToObject(slot, "owner", end_slot->owner.addr);
cJSON_AddItemToArray(slot_array, slot);
- start_slot=end_slot=iterator;
+ start_slot = end_slot = iterator;
}
- char* payload=NULL;
- payload=cJSON_Print(slot_array);
+ char *payload = NULL;
+ payload = cJSON_Print(slot_array);
cJSON_Delete(slot_array);
- json_sds=sdsnew(payload);
+ json_sds = sdsnew(payload);
free(payload);
return json_sds;
}
void json2keyslots(sds json_buffer, void *slot_container_base, size_t sz_slot_container, size_t offset_slot, size_t n_slot_container)
{
- cJSON *slot_table=NULL, *range=NULL, *slot=NULL, *owner=NULL;
- int i=0, j=0, k=0, n_record=0;
- int range_start=0, range_end=0;
- slot_table=cJSON_Parse(json_buffer);
- n_record=cJSON_GetArraySize(slot_table);
- assert(n_slot_container==KEYSPACE_SLOT_NUM);
- struct key_slot *iterator=NULL;
- for(i=0; i<n_record; i++)
- {
- slot=cJSON_GetArrayItem(slot_table, i);
- range=cJSON_GetObjectItem(slot, "slot");
- if(strstr(range->valuestring, "-"))
+ cJSON *slot_table = NULL, *range = NULL, *slot = NULL, *owner = NULL;
+ int i = 0, j = 0, k = 0, n_record = 0;
+ int range_start = 0, range_end = 0;
+ slot_table = cJSON_Parse(json_buffer);
+ n_record = cJSON_GetArraySize(slot_table);
+ assert(n_slot_container == KEYSPACE_SLOT_NUM);
+ struct key_slot *iterator = NULL;
+ for (i = 0; i < n_record; i++)
+ {
+ slot = cJSON_GetArrayItem(slot_table, i);
+ range = cJSON_GetObjectItem(slot, "slot");
+ if (strstr(range->valuestring, "-"))
{
sscanf(range->valuestring, "%d-%d", &range_start, &range_end);
}
else
{
sscanf(range->valuestring, "%d", &range_start);
- range_end=range_start;
+ range_end = range_start;
}
- owner=cJSON_GetObjectItem(slot, "owner");
- for(j=range_start; j<range_end+1; j++)
+ owner = cJSON_GetObjectItem(slot, "owner");
+ for (j = range_start; j < range_end + 1; j++)
{
- iterator=(struct key_slot*)(slot_container_base+sz_slot_container*j+offset_slot);
- iterator->slot_id=j;
+ iterator = (struct key_slot *)(slot_container_base + sz_slot_container * j + offset_slot);
+ iterator->slot_id = j;
node_init_from_cstr(&iterator->owner, owner->valuestring);
k++;
}
}
- assert(k==KEYSPACE_SLOT_NUM);
+ assert(k == KEYSPACE_SLOT_NUM);
cJSON_Delete(slot_table);
return;
}
void health_response2active_nodes(const char *resp_buff, node_t *nodes, uuid_t *uuids, size_t *n_node)
{
- size_t n_record=0, i=0;
- cJSON *health_reponse=NULL, *record=NULL, *service=NULL;
- cJSON *ip=NULL, *port=NULL, *meta=NULL, *meta_node_uuid=NULL;
- health_reponse=cJSON_Parse(resp_buff);
- n_record=cJSON_GetArraySize(health_reponse);
- for(i=0; i<n_record && i<*n_node; i++)
- {
- record=cJSON_GetArrayItem(health_reponse, i);
- service=cJSON_GetObjectItem(record, "Service");
- ip=cJSON_GetObjectItem(service, "Address");
- port=cJSON_GetObjectItem(service, "Port");
- node_init(nodes+i, ip->valuestring, (unsigned int)port->valueint);
- if(uuids)
+ size_t n_record = 0, i = 0;
+ cJSON *health_reponse = NULL, *record = NULL, *service = NULL;
+ cJSON *ip = NULL, *port = NULL, *meta = NULL, *meta_node_uuid = NULL;
+ health_reponse = cJSON_Parse(resp_buff);
+ n_record = cJSON_GetArraySize(health_reponse);
+ for (i = 0; i < n_record && i < *n_node; i++)
+ {
+ record = cJSON_GetArrayItem(health_reponse, i);
+ service = cJSON_GetObjectItem(record, "Service");
+ ip = cJSON_GetObjectItem(service, "Address");
+ port = cJSON_GetObjectItem(service, "Port");
+ node_init(nodes + i, ip->valuestring, (unsigned int)port->valueint);
+ if (uuids)
{
- meta=cJSON_GetObjectItem(service, "Meta");
- meta_node_uuid=cJSON_GetObjectItem(meta, "node_uuid");
- uuid_parse(meta_node_uuid->valuestring, uuids[i]);
+ meta = cJSON_GetObjectItem(service, "Meta");
+ meta_node_uuid = cJSON_GetObjectItem(meta, "node_uuid");
+ uuid_parse(meta_node_uuid->valuestring, uuids[i]);
}
}
cJSON_Delete(health_reponse);
- *n_node=i;
+ *n_node = i;
}
sds node_print_json(const node_t *self, uuid_t uuid)
{
- cJSON* node_info=NULL;
+ cJSON *node_info = NULL;
char uuid_str[MAX_UUID_STR_LEN];
uuid_unparse_lower(uuid, uuid_str);
- node_info=cJSON_CreateObject();
+ node_info = cJSON_CreateObject();
cJSON_AddStringToObject(node_info, "node", self->addr);
cJSON_AddStringToObject(node_info, "node_uuid", uuid_str);
- char* payload=NULL;
- payload=cJSON_Print(node_info);
+ char *payload = NULL;
+ payload = cJSON_Print(node_info);
cJSON_Delete(node_info);
- node_info=NULL;
-
- sds self_json=NULL;
- self_json=sdsnew(payload);
+ node_info = NULL;
+
+ sds self_json = NULL;
+ self_json = sdsnew(payload);
free(payload);
return self_json;
}
void leader_response2leader_node(const char *resp_body, node_t *leader)
{
- cJSON *root=NULL;
- cJSON *item=NULL;
- root=cJSON_Parse(resp_body);
- item=cJSON_GetObjectItem(root, "node");
- node_init_from_cstr(leader, item->valuestring);;
+ cJSON *root = NULL;
+ cJSON *item = NULL;
+ root = cJSON_Parse(resp_body);
+ item = cJSON_GetObjectItem(root, "node");
+ node_init_from_cstr(leader, item->valuestring);
+ ;
cJSON_Delete(root);
}
/* This is an modified version of keyHashSlot of Redis source code.
* If the key contains the {...} pattern, only the part between
* { and } is hashed. This is to force certain keys to be in
- * the same node.
-*/
-#define KEYSPACE_XXHASH_SEED 5210
+ * the same node.
+ */
+#define KEYSPACE_XXHASH_SEED 5210
int key_hash_slot(const char *key, size_t keylen)
{
- int slot_id=-1;
- int s=0, e=0; /* start-end indexes of { and } */
+ int slot_id = -1;
+ int s = 0, e = 0; /* start-end indexes of { and } */
- for (s = 0; s < keylen; s++)
- if (key[s] == '{') break;
+ for (s = 0; s < keylen; s++)
+ if (key[s] == '{')
+ break;
- /* No '{' ? Hash the whole key. This is the base case. */
- if (s == keylen)
+ /* No '{' ? Hash the whole key. This is the base case. */
+ if (s == keylen)
{
- slot_id=XXH32(key, keylen, KEYSPACE_XXHASH_SEED)%KEYSPACE_SLOT_NUM;
+ slot_id = XXH32(key, keylen, KEYSPACE_XXHASH_SEED) % KEYSPACE_SLOT_NUM;
return slot_id;
}
- /* '{' found? Check if we have the corresponding '}'. */
- for (e = s+1; e < keylen; e++)
- if (key[e] == '}') break;
+ /* '{' found? Check if we have the corresponding '}'. */
+ for (e = s + 1; e < keylen; e++)
+ if (key[e] == '}')
+ break;
- /* No '}' or nothing between {} ? Hash the whole key. */
- if (e == keylen || e == s+1)
+ /* No '}' or nothing between {} ? Hash the whole key. */
+ if (e == keylen || e == s + 1)
{
- slot_id=XXH32(key, keylen, KEYSPACE_XXHASH_SEED)%KEYSPACE_SLOT_NUM;
+ slot_id = XXH32(key, keylen, KEYSPACE_XXHASH_SEED) % KEYSPACE_SLOT_NUM;
return slot_id;
}
- return XXH32(key+s+1, e-s-1, KEYSPACE_XXHASH_SEED)%KEYSPACE_SLOT_NUM;
+ return XXH32(key + s + 1, e - s - 1, KEYSPACE_XXHASH_SEED) % KEYSPACE_SLOT_NUM;
}
int key2tid(const sds key, int nr_worker_threads)
{
- return key_hash_slot(key, sdslen(key))%nr_worker_threads;
+ return key_hash_slot(key, sdslen(key)) % nr_worker_threads;
}
-//Source: https://stackoverflow.com/a/779960
-char *str_replace(char *orig, char *rep, char *with)
-{
- char *result; // the return string
- char *ins; // the next insert point
- char *tmp; // varies
- int len_rep; // length of rep (the string to remove)
- int len_with; // length of with (the string to replace rep with)
- int len_front; // distance between rep and end of last rep
- int count; // number of replacements
+// Source: https://stackoverflow.com/a/779960
+char *str_replace(char *orig, char *rep, char *with)
+{
+ char *result; // the return string
+ char *ins; // the next insert point
+ char *tmp; // varies
+ int len_rep; // length of rep (the string to remove)
+ int len_with; // length of with (the string to replace rep with)
+ int len_front; // distance between rep and end of last rep
+ int count; // number of replacements
- // sanity checks and initialization
- if (!orig || !rep)
- return NULL;
- len_rep = strlen(rep);
- if (len_rep == 0)
- return NULL; // empty rep causes infinite loop during count
- if (!with)
- with = "";
- len_with = strlen(with);
+ // sanity checks and initialization
+ if (!orig || !rep)
+ return NULL;
+ len_rep = strlen(rep);
+ if (len_rep == 0)
+ return NULL; // empty rep causes infinite loop during count
+ if (!with)
+ with = "";
+ len_with = strlen(with);
- // count the number of replacements needed
- ins = orig;
- for (count = 0; (tmp = strstr(ins, rep)); ++count) {
- ins = tmp + len_rep;
- }
+ // count the number of replacements needed
+ ins = orig;
+ for (count = 0; (tmp = strstr(ins, rep)); ++count)
+ {
+ ins = tmp + len_rep;
+ }
- tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);
+ tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);
- if (!result)
- return NULL;
+ if (!result)
+ return NULL;
- // first time through the loop, all the variable are set correctly
- // from here on,
- // tmp points to the end of the result string
- // ins points to the next occurrence of rep in orig
- // orig points to the remainder of orig after "end of rep"
- while (count--) {
- ins = strstr(orig, rep);
- len_front = ins - orig;
- tmp = strncpy(tmp, orig, len_front) + len_front;
- tmp = strcpy(tmp, with) + len_with;
- orig += len_front + len_rep; // move to next "end of rep"
- }
- strcpy(tmp, orig);
- return result;
+ // first time through the loop, all the variable are set correctly
+ // from here on,
+ // tmp points to the end of the result string
+ // ins points to the next occurrence of rep in orig
+ // orig points to the remainder of orig after "end of rep"
+ while (count--)
+ {
+ ins = strstr(orig, rep);
+ len_front = ins - orig;
+ tmp = strncpy(tmp, orig, len_front) + len_front;
+ tmp = strcpy(tmp, with) + len_with;
+ orig += len_front + len_rep; // move to next "end of rep"
+ }
+ strcpy(tmp, orig);
+ return result;
}
int swarmkv_cmd_parse_integer(const struct swarmkv_cmd *cmd, const char *name, long long *integer)
{
- if(cmd->argc<2)
+ if (cmd->argc < 2)
{
return -1;
}
- for(int i=0; i<cmd->argc; i++)
+ for (int i = 0; i < cmd->argc; i++)
{
- if(0==strcasecmp(cmd->argv[i], name))
+ if (0 == strcasecmp(cmd->argv[i], name))
{
- if(i+1<cmd->argc)
+ if (i + 1 < cmd->argc)
{
- return str2integer(cmd->argv[i+1], integer);
+ return str2integer(cmd->argv[i + 1], integer);
}
else
{
@@ -838,17 +850,17 @@ int swarmkv_cmd_parse_integer(const struct swarmkv_cmd *cmd, const char *name, l
}
int swarmkv_cmd_parse_double(const struct swarmkv_cmd *cmd, const char *name, double *dval)
{
- if(cmd->argc<2)
+ if (cmd->argc < 2)
{
return -1;
}
- for(int i=0; i<cmd->argc; i++)
+ for (int i = 0; i < cmd->argc; i++)
{
- if(0==strcasecmp(cmd->argv[i], name))
+ if (0 == strcasecmp(cmd->argv[i], name))
{
- if(i+1<cmd->argc)
+ if (i + 1 < cmd->argc)
{
- *dval=strtod(cmd->argv[i+1], NULL);
+ *dval = strtod(cmd->argv[i + 1], NULL);
return 0;
}
else
diff --git a/src/swarmkv_common.h b/src/swarmkv_common.h
index d4f53e5..a775124 100644
--- a/src/swarmkv_common.h
+++ b/src/swarmkv_common.h
@@ -62,6 +62,7 @@ struct swarmkv_options
unsigned int health_check_announce_port;
int dryrun;
int run_for_leader_enabled;
+ int network_compression_enabled;
unsigned int consul_port;
unsigned int cluster_timeout_us;
unsigned int sync_interval_us;
diff --git a/src/swarmkv_core.h b/src/swarmkv_core.h
deleted file mode 100644
index 365851d..0000000
--- a/src/swarmkv_core.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-#include "swarmkv.h"
-#include "swarmkv_common.h"
-void exec_for_local(struct swarmkv *db, const struct swarmkv_cmd *cmd, const node_t *target_node, swarmkv_on_reply_callback_t * cb, void * cb_arg);
-struct event_base *swarmkv_get_event_base(struct swarmkv *db); \ No newline at end of file
diff --git a/src/swarmkv_keyspace.c b/src/swarmkv_keyspace.c
index 582cf52..8990b1a 100644
--- a/src/swarmkv_keyspace.c
+++ b/src/swarmkv_keyspace.c
@@ -24,19 +24,13 @@
#include <string.h>
#include <sys/syscall.h>
+// #define CONSUL_HOST "127.0.0.1"
+#define CONSUL_HOST "localhost"
+#define CONSUL_DEFAULT_PORT 8500
+#define LOCAL_HOST "127.0.0.1"
-
-
-//#define CONSUL_HOST "127.0.0.1"
-#define CONSUL_HOST "localhost"
-#define CONSUL_DEFAULT_PORT 8500
-
-#define LOCAL_HOST "127.0.0.1"
-
-
-#define MODULE_SWARMKV_KEYSPACE module_name_str("swarmkv.keyspace")
-
+#define MODULE_SWARMKV_KEYSPACE module_name_str("swarmkv.keyspace")
struct replica_node
{
@@ -45,33 +39,32 @@ struct replica_node
};
struct key_route_entry
{
- sds key;
+ sds key;
struct replica_node *hash_replica;
uint64_t abs_timeout;
char is_expiring;
struct timeout timeout_handle;
UT_hash_handle hh;
};
-struct key_route_entry *key_entry_new_len(const char* key, size_t key_len)
+struct key_route_entry *key_entry_new_len(const char *key, size_t key_len)
{
- struct key_route_entry *entry=NULL;
- entry=ALLOC(struct key_route_entry, 1);
- entry->key=sdsnewlen(key, key_len);
+ struct key_route_entry *entry = NULL;
+ entry = ALLOC(struct key_route_entry, 1);
+ entry->key = sdsnewlen(key, key_len);
return entry;
-
}
struct key_route_entry *key_entry_new(const sds key)
{
- struct key_route_entry *entry=NULL;
- entry=key_entry_new_len(key, sdslen(key));
+ struct key_route_entry *entry = NULL;
+ entry = key_entry_new_len(key, sdslen(key));
return entry;
}
void key_entry_free(struct key_route_entry *key_entry)
{
sdsfree(key_entry->key);
- key_entry->key=NULL;
- struct replica_node *replica=NULL, *tmp=NULL;
+ key_entry->key = NULL;
+ struct replica_node *replica = NULL, *tmp = NULL;
HASH_ITER(hh, key_entry->hash_replica, replica, tmp)
{
HASH_DELETE(hh, key_entry->hash_replica, replica);
@@ -81,13 +74,13 @@ void key_entry_free(struct key_route_entry *key_entry)
}
int key_entry_add_replica_node(struct key_route_entry *key_entry, const node_t *node)
{
- struct replica_node *tmp=NULL;
+ struct replica_node *tmp = NULL;
HASH_FIND(hh, key_entry->hash_replica, node, sizeof(node_t), tmp);
- if(tmp)
+ if (tmp)
{
return 0;
}
- tmp=ALLOC(struct replica_node, 1);
+ tmp = ALLOC(struct replica_node, 1);
node_copy(&tmp->node, node);
HASH_ADD(hh, key_entry->hash_replica, node, sizeof(node_t), tmp);
return 1;
@@ -95,10 +88,10 @@ int key_entry_add_replica_node(struct key_route_entry *key_entry, const node_t *
int key_entry_rdel_replica_node(struct key_route_entry *key_entry, const node_t *node)
{
- struct replica_node *found=NULL;
+ struct replica_node *found = NULL;
HASH_FIND(hh, key_entry->hash_replica, node, sizeof(node_t), found);
- if(found)
+ if (found)
{
HASH_DEL(key_entry->hash_replica, found);
return 1;
@@ -111,22 +104,22 @@ int key_entry_rdel_replica_node(struct key_route_entry *key_entry, const node_t
struct swarmkv_reply *key_entry_list_replica_nodes(struct key_route_entry *key_entry)
{
- struct swarmkv_reply *reply=NULL;
- size_t n_existed_replica=0, i=0;
- struct replica_node *replica=NULL, *tmp=NULL;
+ struct swarmkv_reply *reply = NULL;
+ size_t n_existed_replica = 0, i = 0;
+ struct replica_node *replica = NULL, *tmp = NULL;
- n_existed_replica=HASH_COUNT(key_entry->hash_replica);
- reply=swarmkv_reply_new_array(n_existed_replica);
+ n_existed_replica = HASH_COUNT(key_entry->hash_replica);
+ reply = swarmkv_reply_new_array(n_existed_replica);
HASH_ITER(hh, key_entry->hash_replica, replica, tmp)
{
- reply->elements[i]=swarmkv_reply_new_node(&replica->node, 0);
+ reply->elements[i] = swarmkv_reply_new_node(&replica->node, 0);
i++;
}
return reply;
}
static int slot_is_my_thread(int slot_id, int thread_id, int nr_threads)
{
- return (slot_id%nr_threads)==thread_id;
+ return (slot_id % nr_threads) == thread_id;
}
struct crdt_op_ctx
{
@@ -140,14 +133,14 @@ void crdt_op_ctx_free(struct crdt_op_ctx *ctx)
free(ctx);
}
-void crdt_op_on_reply(const struct swarmkv_reply *reply, void * arg)
+void crdt_op_on_reply(const struct swarmkv_reply *reply, void *arg)
{
- struct crdt_op_ctx *ctx = (struct crdt_op_ctx*)arg;
- if(ctx->is_del)
+ struct crdt_op_ctx *ctx = (struct crdt_op_ctx *)arg;
+ if (ctx->is_del)
{
- if(reply->type==SWARMKV_REPLY_INTEGER && reply->integer !=1)
+ if (reply->type == SWARMKV_REPLY_INTEGER && reply->integer != 1)
{
- // printf("crdt del %s at %s:%u failed.\n", ctx->key, ctx->peer.ip_addr, ctx->peer.cluster_port);
+ // printf("crdt del %s at %s:%u failed.\n", ctx->key, ctx->peer.ip_addr, ctx->peer.cluster_port);
}
}
crdt_op_ctx_free(ctx);
@@ -155,22 +148,22 @@ void crdt_op_on_reply(const struct swarmkv_reply *reply, void * arg)
}
void key_entry_deletion_notification(struct key_route_entry *key_entry, struct swarmkv *exec_cmd_handle)
{
- struct replica_node *replica=NULL, *tmp=NULL;
+ struct replica_node *replica = NULL, *tmp = NULL;
const char *argv[3];
size_t argv_len[3];
- argv[0]="crdt";
- argv_len[0]=strlen(argv[0]);
- argv[1]="del";
- argv_len[1]=strlen(argv[1]);
- argv[2]=key_entry->key;
- argv_len[2]=sdslen(key_entry->key);
+ argv[0] = "crdt";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = "del";
+ argv_len[1] = strlen(argv[1]);
+ argv[2] = key_entry->key;
+ argv_len[2] = sdslen(key_entry->key);
HASH_ITER(hh, key_entry->hash_replica, replica, tmp)
{
- struct crdt_op_ctx *ctx=ALLOC(struct crdt_op_ctx, 1);
+ struct crdt_op_ctx *ctx = ALLOC(struct crdt_op_ctx, 1);
node_copy(&ctx->peer, &replica->node);
- ctx->key=sdsdup(key_entry->key);
- ctx->is_del=1;
+ ctx->key = sdsdup(key_entry->key);
+ ctx->is_del = 1;
swarmkv_async_command_on_argv(exec_cmd_handle, crdt_op_on_reply, ctx, replica->node.addr, 3, argv, argv_len);
}
return;
@@ -178,29 +171,29 @@ void key_entry_deletion_notification(struct key_route_entry *key_entry, struct s
void key_entry_meet_replica(struct key_route_entry *key_entry, struct swarmkv *exec_cmd_handle)
{
- struct replica_node *replica=NULL, *tmp=NULL;
- int n_replica=HASH_COUNT(key_entry->hash_replica), i=0;
- const char *argv[3+n_replica];
- size_t argv_len[3+n_replica];
- argv[0]="crdt";
- argv_len[0]=strlen(argv[0]);
- argv[1]="meet";
- argv_len[1]=strlen(argv[1]);
- argv[2]=key_entry->key;
- argv_len[2]=sdslen(key_entry->key);
+ struct replica_node *replica = NULL, *tmp = NULL;
+ int n_replica = HASH_COUNT(key_entry->hash_replica), i = 0;
+ const char *argv[3 + n_replica];
+ size_t argv_len[3 + n_replica];
+ argv[0] = "crdt";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = "meet";
+ argv_len[1] = strlen(argv[1]);
+ argv[2] = key_entry->key;
+ argv_len[2] = sdslen(key_entry->key);
HASH_ITER(hh, key_entry->hash_replica, replica, tmp)
{
- argv[3+i]=node_addr2cstr(&replica->node);
- argv_len[3+i]=strlen(argv[3+i]);
+ argv[3 + i] = node_addr2cstr(&replica->node);
+ argv_len[3 + i] = strlen(argv[3 + i]);
i++;
}
- assert(i==n_replica);
+ assert(i == n_replica);
HASH_ITER(hh, key_entry->hash_replica, replica, tmp)
{
- struct crdt_op_ctx *ctx=ALLOC(struct crdt_op_ctx, 1);
+ struct crdt_op_ctx *ctx = ALLOC(struct crdt_op_ctx, 1);
node_copy(&ctx->peer, &replica->node);
- ctx->key=sdsdup(key_entry->key);
- swarmkv_async_command_on_argv(exec_cmd_handle, crdt_op_on_reply, ctx, replica->node.addr, 3+n_replica, argv, argv_len);
+ ctx->key = sdsdup(key_entry->key);
+ swarmkv_async_command_on_argv(exec_cmd_handle, crdt_op_on_reply, ctx, replica->node.addr, 3 + n_replica, argv, argv_len);
}
return;
}
@@ -209,14 +202,14 @@ struct slot_runtime
{
struct key_slot slot;
enum slot_state state;
- node_t rebalancing_peer;//rebalancing_peer is used for state MIGRATING and IMPORTING
+ node_t rebalancing_peer; // rebalancing_peer is used for state MIGRATING and IMPORTING
struct key_route_entry *keyroute_table;
};
void http_connection_close_callback(struct evhttp_connection *conn, void *arg)
{
-// struct consul_task *task=(struct consul_task *)arg;
- //printf("http connection %s %p closed\n", task->task_name, conn);
+ // struct consul_task *task=(struct consul_task *)arg;
+ // printf("http connection %s %p closed\n", task->task_name, conn);
return;
}
struct ks_thread
@@ -227,8 +220,7 @@ struct ks_thread
int consul_slots_modify_idx;
int consul_nodes_modify_idx;
struct swarmkv_keyspace *ref_ks;
- struct event_base *evbase; //reference of swarmkv
-
+ struct event_base *evbase; // reference of swarmkv
};
struct swarmkv_keyspace
{
@@ -240,7 +232,6 @@ struct swarmkv_keyspace
node_t self;
uuid_t uuid;
-
struct ks_thread *threads;
struct slot_runtime slot_rts[KEYSPACE_SLOT_NUM];
@@ -259,79 +250,73 @@ struct swarmkv_keyspace
struct evhttp *http_server;
-
- //reference, no need free
+ // reference, no need free
struct swarmkv *exec_cmd_handle;
struct swarmkv_module *mod_monitor;
struct log_handle *logger;
-
};
-
struct http_client;
-void consul_acquire_session_lock_async(struct ks_thread* thr);
-void consul_watch_leadership_changes_async(struct ks_thread* thr);
-
-void consul_watch_nodes_changes_async(struct ks_thread* ks);
-void consul_watch_slots_changes_async(struct ks_thread* ks);
+void consul_acquire_session_lock_async(struct ks_thread *thr);
+void consul_watch_leadership_changes_async(struct ks_thread *thr);
+void consul_watch_nodes_changes_async(struct ks_thread *ks);
+void consul_watch_slots_changes_async(struct ks_thread *ks);
void health_check_cb(struct evhttp_request *request, void *arg)
{
- struct swarmkv_keyspace *ks=(struct swarmkv_keyspace *)arg;
- struct evbuffer* evbuf_reply = evbuffer_new();
+ struct swarmkv_keyspace *ks = (struct swarmkv_keyspace *)arg;
+ struct evbuffer *evbuf_reply = evbuffer_new();
struct evkeyvalq *output_headers = evhttp_request_get_output_headers(request);
- //HTTP header
+ // HTTP header
evhttp_add_header(output_headers, "Server", GIT_VERSION);
- evhttp_add_header(output_headers, "Content-Type", "text/plain; charset=UTF-8");//utf8
+ evhttp_add_header(output_headers, "Content-Type", "text/plain; charset=UTF-8"); // utf8
evhttp_add_header(output_headers, "Connection", "close");
-
+
evbuffer_add_printf(evbuf_reply, "SwarmKV node of cluster %s is running", ks->db_name);
evhttp_send_reply(request, HTTP_OK, "OK", evbuf_reply);
evbuffer_free(evbuf_reply);
- struct evhttp_connection *conn=evhttp_request_get_connection(request);
- struct bufferevent * bev=evhttp_connection_get_bufferevent(conn);
+ struct evhttp_connection *conn = evhttp_request_get_connection(request);
+ struct bufferevent *bev = evhttp_connection_get_bufferevent(conn);
bufferevent_priority_set(bev, 0);
return;
}
struct evhttp *http_server_new(struct event_base *evbase, unsigned int *port_listen, void *arg)
{
- struct swarmkv_keyspace *ks=(struct swarmkv_keyspace *)arg;
- void *logger=ks->logger;
- struct evhttp* http = evhttp_new(evbase);
- struct evhttp_bound_socket *bound_socket=NULL;
- bound_socket=evhttp_bind_socket_with_handle(http, "0.0.0.0", *port_listen);
- if(bound_socket==NULL)
- {
- log_fatal(logger, MODULE_SWARMKV_KEYSPACE, "evhttp_bind_socket on port %u failed.", port_listen);
+ struct swarmkv_keyspace *ks = (struct swarmkv_keyspace *)arg;
+ void *logger = ks->logger;
+ struct evhttp *http = evhttp_new(evbase);
+ struct evhttp_bound_socket *bound_socket = NULL;
+ bound_socket = evhttp_bind_socket_with_handle(http, "0.0.0.0", *port_listen);
+ if (bound_socket == NULL)
+ {
+ log_fatal(logger, MODULE_SWARMKV_KEYSPACE, "evhttp_bind_socket on port %u failed.", *port_listen);
return NULL;
- }
- evutil_socket_t sockfd=-1;
- sockfd=evhttp_bound_socket_get_fd(bound_socket);
+ }
+ evutil_socket_t sockfd = -1;
+ sockfd = evhttp_bound_socket_get_fd(bound_socket);
evutil_make_socket_closeonexec(sockfd);
- struct sockaddr_storage ss;
+ struct sockaddr_storage ss;
ev_socklen_t socklen = sizeof(ss);
if (getsockname(sockfd, (struct sockaddr *)&ss, &socklen) < 0)
{
- log_fatal(logger, MODULE_SWARMKV_KEYSPACE, "getsockname from evhttp fd failed.");
+ log_fatal(logger, MODULE_SWARMKV_KEYSPACE, "getsockname from evhttp fd failed.");
}
- if(*port_listen==0)
+ if (*port_listen == 0)
{
- *port_listen=ntohs(((struct sockaddr_in*)&ss)->sin_port);
+ *port_listen = ntohs(((struct sockaddr_in *)&ss)->sin_port);
}
- int http_option_timeout = 5; //in seconds
- evhttp_set_timeout(http, http_option_timeout);
- evhttp_set_allowed_methods( http , EVHTTP_REQ_GET);
- //Set a callback for a specified URI
- evhttp_set_cb(http, "/health", health_check_cb, ks);
+ int http_option_timeout = 5; // in seconds
+ evhttp_set_timeout(http, http_option_timeout);
+ evhttp_set_allowed_methods(http, EVHTTP_REQ_GET);
+ // Set a callback for a specified URI
+ evhttp_set_cb(http, "/health", health_check_cb, ks);
return http;
}
-
-
/*
int consul_get_self_ip(struct swarmkv_keyspace* ks)
{
@@ -349,31 +334,31 @@ int consul_get_self_ip(struct swarmkv_keyspace* ks)
cJSON_Delete(self);
}
//cjson parse
- sdsfree(response);
+ sdsfree(response);
response=NULL;
return ret;
}
*/
-int consul_service_register(struct swarmkv_keyspace* ks)
+int consul_service_register(struct swarmkv_keyspace *ks)
{
- int ret=0;
- char health_check_url[SWARMKV_URL_MAX]="";
+ int ret = 0;
+ char health_check_url[SWARMKV_URL_MAX] = "";
char uuid_str[37];
-
- cJSON* service=cJSON_CreateObject();
+
+ cJSON *service = cJSON_CreateObject();
cJSON_AddStringToObject(service, "Name", ks->db_name);
snprintf(ks->consul_service_id, sizeof(ks->consul_service_id), "%.128s-%d", ks->db_name, ks->opts->cluster_announce_port);
cJSON_AddStringToObject(service, "ID", ks->consul_service_id);
cJSON_AddStringToObject(service, "Address", ks->opts->cluster_announce_ip);
cJSON_AddNumberToObject(service, "Port", ks->opts->cluster_announce_port);
- cJSON* meta=cJSON_CreateObject();
+ cJSON *meta = cJSON_CreateObject();
uuid_unparse_lower(ks->uuid, uuid_str);
cJSON_AddStringToObject(meta, "node_uuid", uuid_str);
-
+
cJSON_AddItemToObject(service, "Meta", meta);
- cJSON* check=cJSON_CreateObject();
+ cJSON *check = cJSON_CreateObject();
cJSON_AddStringToObject(check, "Name", ks->db_name);
snprintf(ks->consul_check_id, sizeof(ks->consul_check_id), "%.128s-%u", ks->db_name, ks->opts->cluster_announce_port);
@@ -385,19 +370,19 @@ int consul_service_register(struct swarmkv_keyspace* ks)
cJSON_AddStringToObject(check, "DeregisterCriticalServiceAfter", "5m");
cJSON_AddItemToObject(service, "Check", check);
- char* payload=NULL;
- payload=cJSON_Print(service);
- sds req_body=sdsnew(payload);
- //printf("%s\n", req_body);
+ char *payload = NULL;
+ payload = cJSON_Print(service);
+ sds req_body = sdsnew(payload);
+ // printf("%s\n", req_body);
free(payload);
-
- sds resp_body=NULL;
- int resp_code=0;
- resp_code=http_blocking_request(EVHTTP_REQ_PUT, ks->consul_agent_host, ks->consul_agent_port, "/v1/agent/service/register?replace-existing-checks=true",
- req_body, &resp_body);
- if(resp_code!=200)
+
+ sds resp_body = NULL;
+ int resp_code = 0;
+ resp_code = http_blocking_request(EVHTTP_REQ_PUT, ks->consul_agent_host, ks->consul_agent_port, "/v1/agent/service/register?replace-existing-checks=true",
+ req_body, &resp_body);
+ if (resp_code != 200)
{
- ret=-1;
+ ret = -1;
}
sdsfree(req_body);
sdsfree(resp_body);
@@ -407,78 +392,77 @@ int consul_service_register(struct swarmkv_keyspace* ks)
void consul_session_create_on_success(void *result, void *arg)
{
- struct evhttp_request *req=(struct evhttp_request *)result;
- struct ks_thread *thr=(struct ks_thread*)arg;
- int resp_code=0;
- cJSON* session_id=NULL, *session_create_response=NULL;
-
- int is_running_for_leader=0;
+ struct evhttp_request *req = (struct evhttp_request *)result;
+ struct ks_thread *thr = (struct ks_thread *)arg;
+ int resp_code = 0;
+ cJSON *session_id = NULL, *session_create_response = NULL;
+
+ int is_running_for_leader = 0;
- struct evbuffer *buf=NULL;
- buf=evhttp_request_get_input_buffer(req);
+ struct evbuffer *buf = NULL;
+ buf = evhttp_request_get_input_buffer(req);
size_t len = evbuffer_get_length(buf);
- sds out=sdsnewlen(SDS_NOINIT, len);
+ sds out = sdsnewlen(SDS_NOINIT, len);
evbuffer_copyout(buf, out, len);
- resp_code=evhttp_request_get_response_code(req);
- if(resp_code==200)
+ resp_code = evhttp_request_get_response_code(req);
+ if (resp_code == 200)
{
-
- session_create_response=cJSON_Parse(out);
- session_id=cJSON_GetObjectItem(session_create_response, "ID");
+ session_create_response = cJSON_Parse(out);
+ session_id = cJSON_GetObjectItem(session_create_response, "ID");
strncpy(thr->ref_ks->consul_session_id, session_id->valuestring, sizeof(thr->ref_ks->consul_session_id));
cJSON_Delete(session_create_response);
consul_acquire_session_lock_async(thr);
- is_running_for_leader=1;
+ is_running_for_leader = 1;
log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "session %s is created.", thr->ref_ks->consul_session_id);
}
else
{
log_fatal(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "session creation failed: HTTP code %d, %s.",
- resp_code,
- out);
+ resp_code,
+ out);
}
- if(!is_running_for_leader)
+ if (!is_running_for_leader)
{
consul_watch_leadership_changes_async(thr);
}
sdsfree(out);
return;
}
-void consul_session_create_on_fail(enum e_future_error err, const char * what, void * arg)
+void consul_session_create_on_fail(enum e_future_error err, const char *what, void *arg)
{
- struct ks_thread *thr=(struct ks_thread*)arg;
+ struct ks_thread *thr = (struct ks_thread *)arg;
log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "consul session create failed: %s.", what);
return;
}
void consul_create_session_async(struct ks_thread *thr)
{
- cJSON *session=NULL, *service_check_array=NULL, *service_check=NULL;
- session=cJSON_CreateObject();
+ cJSON *session = NULL, *service_check_array = NULL, *service_check = NULL;
+ session = cJSON_CreateObject();
cJSON_AddStringToObject(session, "LockDelay", "5s");
cJSON_AddStringToObject(session, "Name", "swarmkv-leader-election-lock");
cJSON_AddStringToObject(session, "Behavior", "release");
- service_check=cJSON_CreateObject();
+ service_check = cJSON_CreateObject();
cJSON_AddStringToObject(service_check, "ID", thr->ref_ks->consul_check_id);
- service_check_array=cJSON_CreateArray();
+ service_check_array = cJSON_CreateArray();
cJSON_AddItemToArray(service_check_array, service_check);
cJSON_AddItemToObject(session, "ServiceChecks", service_check_array);
- char *payload=NULL;
- payload=cJSON_Print(session);
+ char *payload = NULL;
+ payload = cJSON_Print(session);
cJSON_Delete(session);
- char url[SWARMKV_URL_MAX]="";
+ char url[SWARMKV_URL_MAX] = "";
snprintf(url, sizeof(url), "/v1/session/create");
- struct future *f=future_create(__func__, consul_session_create_on_success, consul_session_create_on_fail, thr);
- struct http_request *req=http_request_new(thr->consul_client, __func__, f);
+ struct future *f = future_create(__func__, consul_session_create_on_success, consul_session_create_on_fail, thr);
+ struct http_request *req = http_request_new(thr->consul_client, __func__, f);
struct evkeyvalq *output_headers = http_request_get_output_headers(req);
-
+
struct evbuffer *output_buffer = http_request_get_output_buffer(req);
evbuffer_add(output_buffer, payload, strlen(payload));
char number[64];
@@ -489,36 +473,35 @@ void consul_create_session_async(struct ks_thread *thr)
http_request_make(req, EVHTTP_REQ_PUT, url);
free(payload);
return;
-
}
void consul_session_check_on_success(void *result, void *arg)
{
- int resp_code=0;
- cJSON *session_check=NULL;
- int session_check_array_size=0;
- struct ks_thread *thr=(struct ks_thread*)arg;
- int is_running_for_leader=0;
- struct evhttp_request *req=(struct evhttp_request *)result;
+ int resp_code = 0;
+ cJSON *session_check = NULL;
+ int session_check_array_size = 0;
+ struct ks_thread *thr = (struct ks_thread *)arg;
+ int is_running_for_leader = 0;
+ struct evhttp_request *req = (struct evhttp_request *)result;
- resp_code=evhttp_request_get_response_code(req);
+ resp_code = evhttp_request_get_response_code(req);
- if(resp_code==200)
+ if (resp_code == 200)
{
- struct evbuffer *buf=NULL;
- buf=evhttp_request_get_input_buffer(req);
+ struct evbuffer *buf = NULL;
+ buf = evhttp_request_get_input_buffer(req);
size_t len = evbuffer_get_length(buf);
- sds out=sdsnewlen(SDS_NOINIT, len);
+ sds out = sdsnewlen(SDS_NOINIT, len);
evbuffer_copyout(buf, out, len);
-
- session_check=cJSON_Parse(out);
- session_check_array_size=cJSON_GetArraySize(session_check);
+
+ session_check = cJSON_Parse(out);
+ session_check_array_size = cJSON_GetArraySize(session_check);
cJSON_Delete(session_check);
sdsfree(out);
- if(session_check_array_size==0)
+ if (session_check_array_size == 0)
{
consul_create_session_async(thr);
log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE,
- "session %s is not existed, start to create a new session.", thr->ref_ks->consul_session_id);
+ "session %s is not existed, start to create a new session.", thr->ref_ks->consul_session_id);
memset(thr->ref_ks->consul_session_id, 0, sizeof(thr->ref_ks->consul_session_id));
}
else
@@ -526,60 +509,59 @@ void consul_session_check_on_success(void *result, void *arg)
consul_acquire_session_lock_async(thr);
log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "session %s is valid, run for leader.", thr->ref_ks->consul_session_id);
}
- is_running_for_leader=1;
+ is_running_for_leader = 1;
}
else
{
log_fatal(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "session check failed: HTTP code %d.", resp_code);
}
- if(!is_running_for_leader)
+ if (!is_running_for_leader)
{
consul_watch_leadership_changes_async(thr);
}
return;
}
-void consul_session_check_on_fail(enum e_future_error err, const char * what, void * arg)
+void consul_session_check_on_fail(enum e_future_error err, const char *what, void *arg)
{
- struct ks_thread *thr=(struct ks_thread*)arg;
+ struct ks_thread *thr = (struct ks_thread *)arg;
log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "consul session check failed: %s.", what);
return;
}
void consul_session_check_async(struct ks_thread *thr)
{
- assert(thr->thread_id==0);
- char url[SWARMKV_URL_MAX]="";
+ assert(thr->thread_id == 0);
+ char url[SWARMKV_URL_MAX] = "";
snprintf(url, sizeof(url), "/v1/session/info/%s", thr->ref_ks->consul_session_id);
-
- struct future *f=future_create(__func__, consul_session_check_on_success, consul_session_check_on_fail, thr);
- struct http_request *req=http_request_new(thr->consul_client, __func__, f);
+
+ struct future *f = future_create(__func__, consul_session_check_on_success, consul_session_check_on_fail, thr);
+ struct http_request *req = http_request_new(thr->consul_client, __func__, f);
http_request_make(req, EVHTTP_REQ_GET, url);
return;
-
}
void acquire_session_lock_on_success(void *result, void *arg)
{
- struct evhttp_request *req=(struct evhttp_request *)result;
- struct ks_thread *thr=(struct ks_thread*)arg;
- int resp_code=0;
+ struct evhttp_request *req = (struct evhttp_request *)result;
+ struct ks_thread *thr = (struct ks_thread *)arg;
+ int resp_code = 0;
- resp_code=evhttp_request_get_response_code(req);
- if(resp_code==200)
+ resp_code = evhttp_request_get_response_code(req);
+ if (resp_code == 200)
{
- struct evbuffer *buf=NULL;
- buf=evhttp_request_get_input_buffer(req);
+ struct evbuffer *buf = NULL;
+ buf = evhttp_request_get_input_buffer(req);
size_t len = evbuffer_get_length(buf);
- sds resp_body_buff=sdsnewlen(SDS_NOINIT, len);
+ sds resp_body_buff = sdsnewlen(SDS_NOINIT, len);
evbuffer_copyout(buf, resp_body_buff, len);
- if(0==strncmp(resp_body_buff, "true", strlen("true")))
+ if (0 == strncmp(resp_body_buff, "true", strlen("true")))
{
- thr->ref_ks->is_leader=1;
+ thr->ref_ks->is_leader = 1;
log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "become cluster leader.");
}
else
{
log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "lose the election.");
- thr->ref_ks->is_leader=0;
+ thr->ref_ks->is_leader = 0;
}
sdsfree(resp_body_buff);
}
@@ -589,28 +571,27 @@ void acquire_session_lock_on_success(void *result, void *arg)
}
consul_watch_leadership_changes_async(thr);
}
-void acquire_session_lock_on_fail(enum e_future_error err, const char * what, void * arg)
+void acquire_session_lock_on_fail(enum e_future_error err, const char *what, void *arg)
{
- struct ks_thread *thr=(struct ks_thread*)arg;
+ struct ks_thread *thr = (struct ks_thread *)arg;
log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "consul session lock aquire failed: %s.", what);
consul_watch_leadership_changes_async(thr);
return;
}
void consul_acquire_session_lock_async(struct ks_thread *thr)
{
- assert(thr->thread_id==0);
- sds req_body=node_print_json(&thr->ref_ks->self, thr->ref_ks->uuid);
+ assert(thr->thread_id == 0);
+ sds req_body = node_print_json(&thr->ref_ks->self, thr->ref_ks->uuid);
char url[SWARMKV_URL_MAX];
snprintf(url, sizeof(url), "/v1/kv/swarmkv/%s/lead?acquire=%s", thr->ref_ks->db_name, thr->ref_ks->consul_session_id);
- struct future *f=future_create(__func__, acquire_session_lock_on_success, acquire_session_lock_on_fail, thr);
- struct http_request *req=http_request_new(thr->consul_client, __func__, f);
+ struct future *f = future_create(__func__, acquire_session_lock_on_success, acquire_session_lock_on_fail, thr);
+ struct http_request *req = http_request_new(thr->consul_client, __func__, f);
- struct evbuffer* output_buffer = http_request_get_output_buffer(req);
+ struct evbuffer *output_buffer = http_request_get_output_buffer(req);
evbuffer_add(output_buffer, req_body, sdslen(req_body));
-
char number[64];
struct evkeyvalq *output_headers = http_request_get_output_headers(req);
snprintf(number, sizeof(number), "%zu", sdslen(req_body));
@@ -620,11 +601,10 @@ void consul_acquire_session_lock_async(struct ks_thread *thr)
http_request_make(req, EVHTTP_REQ_PUT, url);
sdsfree(req_body);
-
}
void consul_run_for_leader_async(struct ks_thread *thr)
{
- if(0==strlen(thr->ref_ks->consul_session_id))
+ if (0 == strlen(thr->ref_ks->consul_session_id))
{
consul_create_session_async(thr);
}
@@ -636,134 +616,134 @@ void consul_run_for_leader_async(struct ks_thread *thr)
}
void watch_leadership_changes_on_success(void *result, void *arg)
{
- struct evhttp_request *req=(struct evhttp_request*)result;
- struct ks_thread *thr=(struct ks_thread*)arg;
- assert(thr->thread_id==0);//only thread 0 can run this function
-
+ struct evhttp_request *req = (struct evhttp_request *)result;
+ struct ks_thread *thr = (struct ks_thread *)arg;
+ assert(thr->thread_id == 0); // only thread 0 can run this function
- cJSON *metadata_array=NULL, *metadata=NULL, *modify_idx=NULL, *session=NULL;
- int resp_code=0;
- int is_running_for_leader=0;
+ cJSON *metadata_array = NULL, *metadata = NULL, *modify_idx = NULL, *session = NULL;
+ int resp_code = 0;
+ int is_running_for_leader = 0;
- resp_code=evhttp_request_get_response_code(req);
- if(resp_code==200)
+ resp_code = evhttp_request_get_response_code(req);
+ if (resp_code == 200)
{
- struct evbuffer *buf=NULL;
- buf=evhttp_request_get_input_buffer(req);
+ struct evbuffer *buf = NULL;
+ buf = evhttp_request_get_input_buffer(req);
size_t len = evbuffer_get_length(buf);
- sds resp_body_buff=sdsnewlen(SDS_NOINIT, len);
+ sds resp_body_buff = sdsnewlen(SDS_NOINIT, len);
evbuffer_copyout(buf, resp_body_buff, len);
- metadata_array=cJSON_Parse(resp_body_buff);
- metadata=cJSON_GetArrayItem(metadata_array, 0);
- modify_idx=cJSON_GetObjectItem(metadata, "ModifyIndex");
- thr->ref_ks->consul_lead_key_modify_idx=modify_idx->valueint;
- session=cJSON_GetObjectItem(metadata, "Session");
- if(!session || 0==strlen(session->valuestring))
+ metadata_array = cJSON_Parse(resp_body_buff);
+ metadata = cJSON_GetArrayItem(metadata_array, 0);
+ modify_idx = cJSON_GetObjectItem(metadata, "ModifyIndex");
+ thr->ref_ks->consul_lead_key_modify_idx = modify_idx->valueint;
+ session = cJSON_GetObjectItem(metadata, "Session");
+ if (!session || 0 == strlen(session->valuestring))
{
log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "cluster losts leader, start to run for leader.");
consul_run_for_leader_async(thr);
- is_running_for_leader=1;
+ is_running_for_leader = 1;
}
- if(!session || 0!=strcmp(session->valuestring, thr->ref_ks->consul_session_id))
+ if (!session || 0 != strcmp(session->valuestring, thr->ref_ks->consul_session_id))
{
- if(thr->ref_ks->is_leader)
+ if (thr->ref_ks->is_leader)
{
log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "node is no longer a leader.");
- thr->ref_ks->is_leader=0;
+ thr->ref_ks->is_leader = 0;
}
}
cJSON_Delete(metadata_array);
sdsfree(resp_body_buff);
}
- else if(resp_code==404)
+ else if (resp_code == 404)
{
log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "no leader key, start to run for leader.");
consul_run_for_leader_async(thr);
- is_running_for_leader=1;
+ is_running_for_leader = 1;
}
else
{
log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "watch leadership changes failed: HTTP code %d.", resp_code);
}
-
- if(!is_running_for_leader)
+
+ if (!is_running_for_leader)
{
consul_watch_leadership_changes_async(thr);
}
}
-void watch_leadership_changes_on_fail(enum e_future_error err, const char * what, void * arg)
+void watch_leadership_changes_on_fail(enum e_future_error err, const char *what, void *arg)
{
- struct ks_thread *thr=(struct ks_thread*)arg;
+ struct ks_thread *thr = (struct ks_thread *)arg;
log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "watch leadership changes failed: %s.", what);
return;
}
void consul_watch_leadership_changes_async(struct ks_thread *thr)
{
- char url[SWARMKV_URL_MAX]="";
+ char url[SWARMKV_URL_MAX] = "";
snprintf(url, sizeof(url), "/v1/kv/swarmkv/%s/lead?index=%d&wait=10s", thr->ref_ks->db_name, thr->ref_ks->consul_lead_key_modify_idx);
- struct future *f=future_create(__func__, watch_leadership_changes_on_success, watch_leadership_changes_on_fail, thr);
- struct http_request *req=http_request_new(thr->consul_client, __func__, f);
+ struct future *f = future_create(__func__, watch_leadership_changes_on_success, watch_leadership_changes_on_fail, thr);
+ struct http_request *req = http_request_new(thr->consul_client, __func__, f);
http_request_make(req, EVHTTP_REQ_GET, url);
return;
}
void watch_slots_changes_on_success(void *result, void *arg)
{
- struct evhttp_request *req=(struct evhttp_request*)result;
- struct ks_thread *thr=(struct ks_thread*)arg;
-
- cJSON *metadata_array=NULL, *metadata=NULL, *value=NULL, *modify_idx=NULL;
- int i=0,resp_code=0;
-
- resp_code=evhttp_request_get_response_code(req);
- if(resp_code!=200)
- {
- log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "watch slot changes failed: HTTP code %d.", resp_code);
- consul_watch_slots_changes_async(thr);
- return;
- }
- struct key_slot *new_slots=NULL;
- struct evbuffer *buf=NULL;
- buf=evhttp_request_get_input_buffer(req);
- size_t len = evbuffer_get_length(buf);
- sds resp_body_buff=sdsnewlen(SDS_NOINIT, len);
- evbuffer_copyout(buf, resp_body_buff, len);
-
- metadata_array=cJSON_Parse(resp_body_buff);
- metadata=cJSON_GetArrayItem(metadata_array, 0);
- modify_idx=cJSON_GetObjectItem(metadata, "ModifyIndex");
- thr->consul_slots_modify_idx=modify_idx->valueint;
- value=cJSON_GetObjectItem(metadata, "Value");
- sds decode_buffer=sdsnewlen(NULL, BASE64_DECODE_OUT_SIZE(strlen(value->valuestring)));
- base64_decode(value->valuestring, strlen(value->valuestring), (unsigned char*)decode_buffer);
-
- new_slots=ALLOC(struct key_slot, KEYSPACE_SLOT_NUM);
+ struct evhttp_request *req = (struct evhttp_request *)result;
+ struct ks_thread *thr = (struct ks_thread *)arg;
+
+ cJSON *metadata_array = NULL, *metadata = NULL, *value = NULL, *modify_idx = NULL;
+ int i = 0, resp_code = 0;
+
+ resp_code = evhttp_request_get_response_code(req);
+ if (resp_code != 200)
+ {
+ log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "watch slot changes failed: HTTP code %d.", resp_code);
+ consul_watch_slots_changes_async(thr);
+ return;
+ }
+ struct key_slot *new_slots = NULL;
+ struct evbuffer *buf = NULL;
+ buf = evhttp_request_get_input_buffer(req);
+ size_t len = evbuffer_get_length(buf);
+ sds resp_body_buff = sdsnewlen(SDS_NOINIT, len);
+ evbuffer_copyout(buf, resp_body_buff, len);
+
+ metadata_array = cJSON_Parse(resp_body_buff);
+ metadata = cJSON_GetArrayItem(metadata_array, 0);
+ modify_idx = cJSON_GetObjectItem(metadata, "ModifyIndex");
+ thr->consul_slots_modify_idx = modify_idx->valueint;
+ value = cJSON_GetObjectItem(metadata, "Value");
+ sds decode_buffer = sdsnewlen(NULL, BASE64_DECODE_OUT_SIZE(strlen(value->valuestring)));
+ base64_decode(value->valuestring, strlen(value->valuestring), (unsigned char *)decode_buffer);
+
+ new_slots = ALLOC(struct key_slot, KEYSPACE_SLOT_NUM);
json2keyslots(decode_buffer, new_slots, sizeof(struct key_slot), 0, KEYSPACE_SLOT_NUM);
-
+
sdsfree(decode_buffer);
sdsfree(resp_body_buff);
- struct key_slot *slot=NULL;
- struct slot_runtime *slot_rt=NULL;
- node_t *owner=NULL;
+ struct key_slot *slot = NULL;
+ struct slot_runtime *slot_rt = NULL;
+ node_t *owner = NULL;
log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "thread %d key slots update started.", thr->thread_id);
- for(i=0; i<KEYSPACE_SLOT_NUM; i++)
+ for (i = 0; i < KEYSPACE_SLOT_NUM; i++)
{
- if(!slot_is_my_thread(i, thr->thread_id, thr->ref_ks->opts->nr_worker_threads)) continue;
+ if (!slot_is_my_thread(i, thr->thread_id, thr->ref_ks->opts->nr_worker_threads))
+ continue;
- slot_rt=thr->ref_ks->slot_rts+i;
- slot=&slot_rt->slot;
- owner=&(slot->owner);
- if(0!=node_compare(owner, &(new_slots[i].owner)))
- {
+ slot_rt = thr->ref_ks->slot_rts + i;
+ slot = &slot_rt->slot;
+ owner = &(slot->owner);
+ if (0 != node_compare(owner, &(new_slots[i].owner)))
+ {
node_copy(owner, &(new_slots[i].owner));
- if(slot_rt->state!=STATE_STABLE)
+ if (slot_rt->state != STATE_STABLE)
{
-// log_info(ks->logger, MODULE_SWARMKV_KEYSPACE, "slot %d is reset to STABLE state, owner %s:%u.",
-// slot->slot_id, owner->addr.ip_addr, owner->addr.cluster_port);
+ // log_info(ks->logger, MODULE_SWARMKV_KEYSPACE, "slot %d is reset to STABLE state, owner %s:%u.",
+ // slot->slot_id, owner->addr.ip_addr, owner->addr.cluster_port);
memset(&(slot_rt->rebalancing_peer), 0, sizeof(slot_rt->rebalancing_peer));
}
- slot_rt->state=STATE_STABLE;
+ slot_rt->state = STATE_STABLE;
}
}
log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "thread %d key slots update finished.", thr->thread_id);
@@ -772,28 +752,28 @@ void watch_slots_changes_on_success(void *result, void *arg)
consul_watch_slots_changes_async(thr);
return;
}
-void watch_slots_changes_on_fail(enum e_future_error err, const char * what, void * arg)
+void watch_slots_changes_on_fail(enum e_future_error err, const char *what, void *arg)
{
- struct ks_thread *thr=(struct ks_thread*)arg;
+ struct ks_thread *thr = (struct ks_thread *)arg;
consul_watch_slots_changes_async(thr);
}
void consul_watch_slots_changes_async(struct ks_thread *thr)
{
- char url[SWARMKV_URL_MAX]="";
+ char url[SWARMKV_URL_MAX] = "";
snprintf(url, sizeof(url), "/v1/kv/swarmkv/%s/slots?index=%d", thr->ref_ks->db_name, thr->consul_slots_modify_idx);
- struct future *f=future_create(__func__, watch_slots_changes_on_success, watch_slots_changes_on_fail, thr);
- struct http_request *req=http_request_new(thr->consul_client, __func__, f);
+ struct future *f = future_create(__func__, watch_slots_changes_on_success, watch_slots_changes_on_fail, thr);
+ struct http_request *req = http_request_new(thr->consul_client, __func__, f);
http_request_make(req, EVHTTP_REQ_GET, url);
return;
}
void propagate_slot_table_on_success(void *result, void *arg)
{
- struct evhttp_request *req=(struct evhttp_request *)result;
- struct ks_thread *thr=(struct ks_thread*)arg;
- int resp_code=0;
+ struct evhttp_request *req = (struct evhttp_request *)result;
+ struct ks_thread *thr = (struct ks_thread *)arg;
+ int resp_code = 0;
- resp_code=evhttp_request_get_response_code(req);
- if(resp_code==200)
+ resp_code = evhttp_request_get_response_code(req);
+ if (resp_code == 200)
{
log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "key slots table propagate success.");
}
@@ -803,23 +783,23 @@ void propagate_slot_table_on_success(void *result, void *arg)
}
return;
}
-void propagate_slot_table_on_fail(enum e_future_error err, const char * what, void * arg)
+void propagate_slot_table_on_fail(enum e_future_error err, const char *what, void *arg)
{
- struct ks_thread *thr=(struct ks_thread*)arg;
+ struct ks_thread *thr = (struct ks_thread *)arg;
log_fatal(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE, "key slots table propagate failed: %s",
- what);
+ what);
}
void propagate_slot_table_async(struct ks_thread *thr, struct key_slot new_slot[], size_t slot_num)
{
- sds new_slots_json=NULL;
- new_slots_json=keyslots2json(new_slot, sizeof(struct key_slot), 0, KEYSPACE_SLOT_NUM);
- char url[SWARMKV_URL_MAX]="";
+ sds new_slots_json = NULL;
+ new_slots_json = keyslots2json(new_slot, sizeof(struct key_slot), 0, KEYSPACE_SLOT_NUM);
+ char url[SWARMKV_URL_MAX] = "";
snprintf(url, sizeof(url), "/v1/kv/swarmkv/%s/slots", thr->ref_ks->db_name);
- struct future *f=future_create(__func__, propagate_slot_table_on_success, propagate_slot_table_on_fail, thr);
- struct http_request *req=http_request_new(thr->consul_client, __func__, f);
+ struct future *f = future_create(__func__, propagate_slot_table_on_success, propagate_slot_table_on_fail, thr);
+ struct http_request *req = http_request_new(thr->consul_client, __func__, f);
+
+ // evhttp_connection_set_timeout(req->evhttpconn, 20);
-// evhttp_connection_set_timeout(req->evhttpconn, 20);
-
struct evkeyvalq *output_headers = http_request_get_output_headers(req);
char number[64];
snprintf(number, sizeof(number), "%zu", sdslen(new_slots_json));
@@ -828,136 +808,139 @@ void propagate_slot_table_async(struct ks_thread *thr, struct key_slot new_slot[
struct evbuffer *output_buffer = http_request_get_output_buffer(req);
evbuffer_add(output_buffer, new_slots_json, sdslen(new_slots_json));
-
+
http_request_make(req, EVHTTP_REQ_PUT, url);
sdsfree(new_slots_json);
- new_slots_json=NULL;
+ new_slots_json = NULL;
}
void remove_failed_nodes_from_global_slot_table(struct ks_thread *thr, node_t *health_nodes, size_t n_node)
{
- size_t i=0, j=0, k=0;
- size_t slots_number_effect_by_failed_node=0;
- struct key_slot *slots_copy=NULL;
- node_t *new_owner=NULL, *old_owner=NULL;
- assert(thr->thread_id==0);
-// char uuid_str1[37]="", uuid_str2[37]="";
- if(n_node==0)
+ size_t i = 0, j = 0, k = 0;
+ size_t slots_number_effect_by_failed_node = 0;
+ struct key_slot *slots_copy = NULL;
+ node_t *new_owner = NULL, *old_owner = NULL;
+ assert(thr->thread_id == 0);
+ // char uuid_str1[37]="", uuid_str2[37]="";
+ if (n_node == 0)
{
return;
}
- slots_copy=ALLOC(struct key_slot, KEYSPACE_SLOT_NUM);
- for(i=0; i<KEYSPACE_SLOT_NUM; i++)
+ slots_copy = ALLOC(struct key_slot, KEYSPACE_SLOT_NUM);
+ for (i = 0; i < KEYSPACE_SLOT_NUM; i++)
{
- memcpy(slots_copy+i, &(thr->ref_ks->slot_rts[i].slot), sizeof(struct key_slot));
+ memcpy(slots_copy + i, &(thr->ref_ks->slot_rts[i].slot), sizeof(struct key_slot));
}
- for(i=0; i<KEYSPACE_SLOT_NUM; i++)
+ for (i = 0; i < KEYSPACE_SLOT_NUM; i++)
{
- old_owner=&(slots_copy[i].owner);
- for(j=0; j<n_node; j++)
+ old_owner = &(slots_copy[i].owner);
+ for (j = 0; j < n_node; j++)
{
- if(0==node_compare(old_owner, health_nodes+j))
+ if (0 == node_compare(old_owner, health_nodes + j))
{
break;
}
}
- //slot owner has left the cluster.
- if(j==n_node)
+ // slot owner has left the cluster.
+ if (j == n_node)
{
slots_number_effect_by_failed_node++;
}
}
- //For generating compact slot assignment
- //Request body(1155868 bytes) too large, max size: 524288 bytes.
- //See https://www.consul.io/docs/agent/options.html#kv_max_value_size.
- int slots_rebalanced_per_node=slots_number_effect_by_failed_node/n_node;
- int health_node_offset=0;
+ // For generating compact slot assignment
+ // Request body(1155868 bytes) too large, max size: 524288 bytes.
+ // See https://www.consul.io/docs/agent/options.html#kv_max_value_size.
+ int slots_rebalanced_per_node = slots_number_effect_by_failed_node / n_node;
+ int health_node_offset = 0;
- for(i=0; i<KEYSPACE_SLOT_NUM; i++)
+ for (i = 0; i < KEYSPACE_SLOT_NUM; i++)
{
- old_owner=&(slots_copy[i].owner);
- for(j=0; j<n_node; j++)
+ old_owner = &(slots_copy[i].owner);
+ for (j = 0; j < n_node; j++)
{
- if(0==node_compare(old_owner, health_nodes+j))
+ if (0 == node_compare(old_owner, health_nodes + j))
{
break;
}
}
- //slot owner has left the cluster.
- if(j==n_node)
+ // slot owner has left the cluster.
+ if (j == n_node)
{
- if(k==slots_rebalanced_per_node && health_node_offset<n_node-1)
+ if (k == slots_rebalanced_per_node && health_node_offset < n_node - 1)
{
- k=0;
+ k = 0;
health_node_offset++;
}
- new_owner=health_nodes+health_node_offset;
+ new_owner = health_nodes + health_node_offset;
node_copy(old_owner, new_owner);
k++;
}
}
- int changed_slot_start=-1, changed_slot_end=-1;
+ int changed_slot_start = -1, changed_slot_end = -1;
node_t tmp_new_node, tmp_old_node;
- if(slots_number_effect_by_failed_node)
+ if (slots_number_effect_by_failed_node)
{
- for(i=0; i<KEYSPACE_SLOT_NUM; i++)
+ for (i = 0; i < KEYSPACE_SLOT_NUM; i++)
{
- if(0!=node_compare(&thr->ref_ks->slot_rts[i].slot.owner, &slots_copy[i].owner))
+ if (0 != node_compare(&thr->ref_ks->slot_rts[i].slot.owner, &slots_copy[i].owner))
{
- if(changed_slot_start<0)
+ if (changed_slot_start < 0)
{
node_copy(&tmp_old_node, &thr->ref_ks->slot_rts[i].slot.owner);
- changed_slot_start=i;
+ changed_slot_start = i;
}
- changed_slot_end=i;
+ changed_slot_end = i;
node_copy(&tmp_new_node, &slots_copy[i].owner);
}
- else if(changed_slot_end>0)
+ else if (changed_slot_end > 0)
{
log_info(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE,
- "leader %s changes slot %d-%d owner from %s to %s.",
- thr->ref_ks->self.addr, changed_slot_start, changed_slot_end,
- tmp_old_node.addr, tmp_new_node.addr);
- changed_slot_start=changed_slot_end=-1;
+ "leader %s changes slot %d-%d owner from %s to %s.",
+ thr->ref_ks->self.addr, changed_slot_start, changed_slot_end,
+ tmp_old_node.addr, tmp_new_node.addr);
+ changed_slot_start = changed_slot_end = -1;
}
}
propagate_slot_table_async(thr, slots_copy, KEYSPACE_SLOT_NUM);
}
free(slots_copy);
- slots_copy=NULL;
+ slots_copy = NULL;
return;
}
void remove_failed_nodes_from_key_route_table(struct ks_thread *thr, node_t *health_nodes, size_t n_node)
{
- struct key_route_entry *key_entry=NULL, *tmp_entry=NULL;
- struct slot_runtime *slot_rt=NULL;
- struct replica_node *hash_health_node=NULL, *node=NULL, *found=NULL, *tmp_node=NULL;
- size_t n_modified_key=0, n_removed_replica=0;
+ struct key_route_entry *key_entry = NULL, *tmp_entry = NULL;
+ struct slot_runtime *slot_rt = NULL;
+ struct replica_node *hash_health_node = NULL, *node = NULL, *found = NULL, *tmp_node = NULL;
+ size_t n_modified_key = 0, n_removed_replica = 0;
return;
- for(size_t i=0; i<n_node; i++)
+ for (size_t i = 0; i < n_node; i++)
{
- node=ALLOC(struct replica_node, 1);
- node_copy(&node->node, health_nodes+i);
+ node = ALLOC(struct replica_node, 1);
+ node_copy(&node->node, health_nodes + i);
HASH_ADD(hh, hash_health_node, node, sizeof(node_t), node);
}
- for(int slot_id=0; slot_id<KEYSPACE_SLOT_NUM; slot_id++)
+ for (int slot_id = 0; slot_id < KEYSPACE_SLOT_NUM; slot_id++)
{
- if(!slot_is_my_thread(slot_id, thr->thread_id, thr->ref_ks->opts->nr_worker_threads)) continue;
- slot_rt=thr->ref_ks->slot_rts+slot_id;
- if(!node_compare(&slot_rt->slot.owner, &thr->ref_ks->self)) continue;
+ if (!slot_is_my_thread(slot_id, thr->thread_id, thr->ref_ks->opts->nr_worker_threads))
+ continue;
+ slot_rt = thr->ref_ks->slot_rts + slot_id;
+ if (!node_compare(&slot_rt->slot.owner, &thr->ref_ks->self))
+ continue;
HASH_ITER(hh, slot_rt->keyroute_table, key_entry, tmp_entry)
{
- int is_modified=0;
+ int is_modified = 0;
HASH_ITER(hh, key_entry->hash_replica, node, tmp_node)
{
HASH_FIND(hh, hash_health_node, &node->node, sizeof(node->node), found);
- if(!found)
+ if (!found)
{
HASH_DEL(key_entry->hash_replica, node);
n_removed_replica++;
- is_modified=1;
+ is_modified = 1;
}
}
- if(is_modified) n_modified_key++;
+ if (is_modified)
+ n_modified_key++;
}
}
HASH_ITER(hh, hash_health_node, node, tmp_node)
@@ -965,96 +948,96 @@ void remove_failed_nodes_from_key_route_table(struct ks_thread *thr, node_t *hea
HASH_DEL(hash_health_node, node);
free(node);
}
- if(n_modified_key>0)
+ if (n_modified_key > 0)
{
- log_fatal(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE,
- "thread %d modified %zu keys and removes %zu replicas of key route table for handling failed nodes.",
- thr->thread_id, n_modified_key, n_removed_replica);
+ log_fatal(thr->ref_ks->logger, MODULE_SWARMKV_KEYSPACE,
+ "thread %d modified %zu keys and removes %zu replicas of key route table for handling failed nodes.",
+ thr->thread_id, n_modified_key, n_removed_replica);
}
}
void watch_nodes_changes_on_success(void *result, void *arg)
{
- struct evhttp_request *req= (struct evhttp_request *)result;
- struct ks_thread *thr=(struct ks_thread*)arg;
- int resp_code=0;
- const char* tmp=NULL;
+ struct evhttp_request *req = (struct evhttp_request *)result;
+ struct ks_thread *thr = (struct ks_thread *)arg;
+ int resp_code = 0;
+ const char *tmp = NULL;
node_t health_nodes[SWARMKV_NODE_MAX];
memset(health_nodes, 0, sizeof(health_nodes));
- resp_code=evhttp_request_get_response_code(req);
-
- if(resp_code==200)
+ resp_code = evhttp_request_get_response_code(req);
+
+ if (resp_code == 200)
{
- struct evbuffer *buf=NULL;
- buf=evhttp_request_get_input_buffer(req);
+ struct evbuffer *buf = NULL;
+ buf = evhttp_request_get_input_buffer(req);
size_t len = evbuffer_get_length(buf);
- size_t n_node=SWARMKV_NODE_MAX;
- sds resp_body_buff=sdsnewlen(NULL, len);
+ size_t n_node = SWARMKV_NODE_MAX;
+ sds resp_body_buff = sdsnewlen(NULL, len);
evbuffer_copyout(buf, resp_body_buff, len);
health_response2active_nodes(resp_body_buff, health_nodes, NULL, &n_node);
-
+
sdsfree(resp_body_buff);
- struct evkeyvalq *input_headers=evhttp_request_get_input_headers(req);
- tmp=evhttp_find_header(input_headers, "X-Consul-Index");
+ struct evkeyvalq *input_headers = evhttp_request_get_input_headers(req);
+ tmp = evhttp_find_header(input_headers, "X-Consul-Index");
sscanf(tmp, "%d", &thr->consul_nodes_modify_idx);
remove_failed_nodes_from_key_route_table(thr, health_nodes, n_node);
- if(thr->ref_ks->is_leader && thr->thread_id==0)
+ if (thr->ref_ks->is_leader && thr->thread_id == 0)
{
remove_failed_nodes_from_global_slot_table(thr, health_nodes, n_node);
}
}
consul_watch_nodes_changes_async(thr);
}
-void watch_nodes_changes_on_fail(enum e_future_error err, const char * what, void * arg)
+void watch_nodes_changes_on_fail(enum e_future_error err, const char *what, void *arg)
{
- struct ks_thread *thr=(struct ks_thread*)arg;
+ struct ks_thread *thr = (struct ks_thread *)arg;
consul_watch_nodes_changes_async(thr);
}
void consul_watch_nodes_changes_async(struct ks_thread *thr)
{
- char url[SWARMKV_URL_MAX]="";
+ char url[SWARMKV_URL_MAX] = "";
snprintf(url, sizeof(url), "/v1/health/service/%s?passing=1&index=%d&wait=10s", thr->ref_ks->db_name, thr->consul_nodes_modify_idx);
- struct future *f=future_create(__func__, watch_nodes_changes_on_success, watch_nodes_changes_on_fail, thr);
- struct http_request *req=http_request_new(thr->consul_client, __func__, f);
+ struct future *f = future_create(__func__, watch_nodes_changes_on_success, watch_nodes_changes_on_fail, thr);
+ struct http_request *req = http_request_new(thr->consul_client, __func__, f);
http_request_make(req, EVHTTP_REQ_GET, url);
}
void ks_threads_init(struct swarmkv_keyspace *ks, struct event_base *evbases[], int nr_threads)
{
- int i=0, error=0;
- ks->threads=ALLOC(struct ks_thread, ks->opts->nr_worker_threads);
- struct ks_thread *thr=NULL;
- for(i=0; i<nr_threads; i++)
- {
- thr=ks->threads+i;
- thr->thread_id=i;
- thr->expires=timeouts_open(0, &error);
- thr->consul_client=http_client_new(ks->opts->consul_agent_host, ks->opts->consul_port, evbases[i], ks->logger);
- thr->ref_ks=ks;
- thr->evbase=evbases[i];
+ int i = 0, error = 0;
+ ks->threads = ALLOC(struct ks_thread, ks->opts->nr_worker_threads);
+ struct ks_thread *thr = NULL;
+ for (i = 0; i < nr_threads; i++)
+ {
+ thr = ks->threads + i;
+ thr->thread_id = i;
+ thr->expires = timeouts_open(0, &error);
+ thr->consul_client = http_client_new(ks->opts->consul_agent_host, ks->opts->consul_port, evbases[i], ks->logger);
+ thr->ref_ks = ks;
+ thr->evbase = evbases[i];
consul_watch_slots_changes_async(thr);
consul_watch_nodes_changes_async(thr);
}
}
int keyslots_init(struct swarmkv_keyspace *ks)
{
- struct slot_runtime *slot_rt=NULL;
- struct key_slot *slot=NULL;
- for(int i=0; i<KEYSPACE_SLOT_NUM; i++)
+ struct slot_runtime *slot_rt = NULL;
+ struct key_slot *slot = NULL;
+ for (int i = 0; i < KEYSPACE_SLOT_NUM; i++)
{
- slot_rt=ks->slot_rts+i;
- slot=&(slot_rt->slot);
- slot->slot_id=i;
+ slot_rt = ks->slot_rts + i;
+ slot = &(slot_rt->slot);
+ slot->slot_id = i;
node_copy(&slot->owner, &ks->self);
}
- char url[SWARMKV_URL_MAX]="";
- sds resp_body=NULL;
- int resp_code=0;
+ char url[SWARMKV_URL_MAX] = "";
+ sds resp_body = NULL;
+ int resp_code = 0;
snprintf(url, sizeof(url), "/v1/kv/swarmkv/%s/slots?raw=1", ks->db_name);
- resp_code=http_blocking_request(EVHTTP_REQ_GET, ks->consul_agent_host, ks->consul_agent_port, url, NULL, &resp_body);
- if(resp_code!=200)
+ resp_code = http_blocking_request(EVHTTP_REQ_GET, ks->consul_agent_host, ks->consul_agent_port, url, NULL, &resp_body);
+ if (resp_code != 200)
{
return -1;
}
@@ -1064,60 +1047,60 @@ int keyslots_init(struct swarmkv_keyspace *ks)
}
static struct swarmkv_keyspace *module2keyspace(struct swarmkv_module *module)
{
- //type safety check
- assert(0==strcmp(module->name, "keyspace"));
- struct swarmkv_keyspace *ks=container_of(module, struct swarmkv_keyspace, module);
- assert(ks==module->mod_ctx);
+ // type safety check
+ assert(0 == strcmp(module->name, "keyspace"));
+ struct swarmkv_keyspace *ks = container_of(module, struct swarmkv_keyspace, module);
+ assert(ks == module->mod_ctx);
return ks;
}
void swarmkv_keyspace_set_exec_cmd_handle(struct swarmkv_module *mod_keyspace, struct swarmkv *db)
-{
+{
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- ks->exec_cmd_handle=db;
+ ks->exec_cmd_handle = db;
return;
}
-#define MONITOR_KEY_EXPIRE_EVENT_EXPIRE "keyspace-expire-cycle"
+#define MONITOR_KEY_EXPIRE_EVENT_EXPIRE "keyspace-expire-cycle"
void swarmkv_keyspace_set_monitor_handle(struct swarmkv_module *mod_keyspace, struct swarmkv_module *mod_monitor)
{
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- ks->mod_monitor=mod_monitor;
+ ks->mod_monitor = mod_monitor;
swarmkv_monitor_register_event(mod_monitor, MONITOR_KEY_EXPIRE_EVENT_EXPIRE);
return;
}
struct swarmkv_module *swarmkv_keyspace_new(struct event_base *evbases[], int nr_threads, struct swarmkv_options *opts, const char *db_name, struct log_handle *logger, char **err)
{
- struct swarmkv_keyspace *ks=ALLOC(struct swarmkv_keyspace, 1);
+ struct swarmkv_keyspace *ks = ALLOC(struct swarmkv_keyspace, 1);
strncpy(ks->module.name, "keyspace", sizeof(ks->module.name));
- ks->module.mod_ctx=ks;
+ ks->module.mod_ctx = ks;
strncpy(ks->db_name, db_name, sizeof(ks->db_name));
node_init(&ks->self, opts->cluster_announce_ip, opts->cluster_announce_port);
uuid_copy(ks->uuid, opts->bin_uuid);
- ks->opts=opts;
- ks->consul_agent_port=opts->consul_port;
- strncpy(ks->consul_agent_host, opts->consul_agent_host, sizeof(ks->consul_agent_host));
+ ks->opts = opts;
+ ks->consul_agent_port = opts->consul_port;
+ strncpy(ks->consul_agent_host, opts->consul_agent_host, sizeof(ks->consul_agent_host));
ks->logger = logger;
- int ret=-1;
- ret=keyslots_init(ks);
- if(ret<0)
+ int ret = -1;
+ ret = keyslots_init(ks);
+ if (ret < 0)
{
asprintf(err, "key slots init failed.");
- log_fatal(ks->logger, MODULE_SWARMKV_KEYSPACE, "key slots init failed.");
+ log_fatal(ks->logger, MODULE_SWARMKV_KEYSPACE, "key slots init failed.");
goto error_out;
}
- ks->threads=ALLOC(struct ks_thread, ks->opts->nr_worker_threads);
- struct ks_thread *thr=NULL;
- int error=0;
- for(int i=0; i<nr_threads; i++)
- {
- thr=ks->threads+i;
- thr->thread_id=i;
- thr->expires=timeouts_open(0, &error);
- thr->consul_client=http_client_new(ks->opts->consul_agent_host, ks->opts->consul_port, evbases[i], ks->logger);
- thr->ref_ks=ks;
- thr->evbase=evbases[i];
+ ks->threads = ALLOC(struct ks_thread, ks->opts->nr_worker_threads);
+ struct ks_thread *thr = NULL;
+ int error = 0;
+ for (int i = 0; i < nr_threads; i++)
+ {
+ thr = ks->threads + i;
+ thr->thread_id = i;
+ thr->expires = timeouts_open(0, &error);
+ thr->consul_client = http_client_new(ks->opts->consul_agent_host, ks->opts->consul_port, evbases[i], ks->logger);
+ thr->ref_ks = ks;
+ thr->evbase = evbases[i];
consul_watch_slots_changes_async(thr);
consul_watch_nodes_changes_async(thr);
}
@@ -1131,62 +1114,62 @@ error_out:
void swarmkv_keyspace_start(struct swarmkv_module *mod_keyspace)
{
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- if(ks->opts->dryrun)
+ if (ks->opts->dryrun)
{
log_info(ks->logger, MODULE_SWARMKV_KEYSPACE, "start to run on dry run mode.");
return;
}
-
- ks->http_server=http_server_new(ks->threads[0].evbase, &(ks->opts->health_check_port), ks);
- if(!ks->http_server)
+
+ ks->http_server = http_server_new(ks->threads[0].evbase, &(ks->opts->health_check_port), ks);
+ if (!ks->http_server)
{
log_fatal(ks->logger, MODULE_SWARMKV_KEYSPACE, "health check HTTP server start failed.");
return;
}
- if(ks->opts->health_check_announce_port==0)
+ if (ks->opts->health_check_announce_port == 0)
{
- ks->opts->health_check_announce_port=ks->opts->health_check_port;
+ ks->opts->health_check_announce_port = ks->opts->health_check_port;
}
- int ret=0;
- ret=consul_service_register(ks);
- if(ret<0)
- {
+ int ret = 0;
+ ret = consul_service_register(ks);
+ if (ret < 0)
+ {
log_fatal(ks->logger, MODULE_SWARMKV_KEYSPACE, "consul service register failed.");
return;
}
- if(ks->opts->run_for_leader_enabled)
+ if (ks->opts->run_for_leader_enabled)
{
- consul_watch_leadership_changes_async(ks->threads+0);
+ consul_watch_leadership_changes_async(ks->threads + 0);
}
return;
}
-void swarmkv_keyspace_free(struct swarmkv_module* module)
+void swarmkv_keyspace_free(struct swarmkv_module *module)
{
struct swarmkv_keyspace *ks = module2keyspace(module);
- if(ks->http_server)
+ if (ks->http_server)
{
evhttp_free(ks->http_server);
- ks->http_server=NULL;
+ ks->http_server = NULL;
}
- struct key_route_entry *key_entry=NULL, *tmp_key_entry=NULL;
- int i=0;
- struct slot_runtime *slot_rt=NULL;
- for(i=0; i<KEYSPACE_SLOT_NUM; i++)
+ struct key_route_entry *key_entry = NULL, *tmp_key_entry = NULL;
+ int i = 0;
+ struct slot_runtime *slot_rt = NULL;
+ for (i = 0; i < KEYSPACE_SLOT_NUM; i++)
{
- slot_rt=ks->slot_rts+i;
+ slot_rt = ks->slot_rts + i;
HASH_ITER(hh, slot_rt->keyroute_table, key_entry, tmp_key_entry)
{
HASH_DELETE(hh, slot_rt->keyroute_table, key_entry);
key_entry_free(key_entry);
}
}
- for(i=0; i<ks->opts->nr_worker_threads; i++)
+ for (i = 0; i < ks->opts->nr_worker_threads; i++)
{
http_client_free(ks->threads[i].consul_client);
- ks->threads[i].consul_client=NULL;
+ ks->threads[i].consul_client = NULL;
timeouts_close(ks->threads[i].expires);
- ks->threads[i].expires=NULL;
+ ks->threads[i].expires = NULL;
}
free(ks->threads);
free(ks);
@@ -1195,130 +1178,128 @@ void swarmkv_keyspace_free(struct swarmkv_module* module)
void swarmkv_keyspace_info(struct swarmkv_module *mod_keyspace, struct keyspace_info *info)
{
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- int i=0;
- struct slot_runtime *slot_rt=NULL;
+ int i = 0;
+ struct slot_runtime *slot_rt = NULL;
memset(info, 0, sizeof(struct keyspace_info));
- info->health_check_port=ks->opts->health_check_announce_port;
- info->keys=0;
- info->expires=0;
- info->slots=0;
- for(i=0; i<KEYSPACE_SLOT_NUM; i++)
+ info->health_check_port = ks->opts->health_check_announce_port;
+ info->keys = 0;
+ info->expires = 0;
+ info->slots = 0;
+ for (i = 0; i < KEYSPACE_SLOT_NUM; i++)
{
- slot_rt=ks->slot_rts+i;
- if(!node_compare(&slot_rt->slot.owner, &ks->self))
- info->slots++;
- info->keys+=HASH_COUNT(slot_rt->keyroute_table);
+ slot_rt = ks->slot_rts + i;
+ if (!node_compare(&slot_rt->slot.owner, &ks->self))
+ info->slots++;
+ info->keys += HASH_COUNT(slot_rt->keyroute_table);
}
- for(i=0; i<ks->opts->nr_worker_threads; i++)
+ for (i = 0; i < ks->opts->nr_worker_threads; i++)
{
- info->expires+=timeouts_count(ks->threads[i].expires);
+ info->expires += timeouts_count(ks->threads[i].expires);
}
return;
}
enum cmd_exec_result keyslot_command(struct swarmkv_module *mod_keyspace, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
/* KEYSLOT key*/
- char *key=cmd->argv[1];
- int slot_id=key_hash_slot(key, strlen(key));
- *reply=swarmkv_reply_new_integer(slot_id);
+ char *key = cmd->argv[1];
+ int slot_id = key_hash_slot(key, strlen(key));
+ *reply = swarmkv_reply_new_integer(slot_id);
return FINISHED;
}
enum cmd_exec_result keyspace_setslot_command(struct swarmkv_module *mod_keyspace, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* KEYSPACE SETSLOT <slot> IMPORTING|MIGRATING|NODE|STABLE IP:port */
+ /* KEYSPACE SETSLOT <slot> IMPORTING|MIGRATING|NODE|STABLE IP:port */
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
node_t peer_node;
enum slot_state state;
- sds str_state=cmd->argv[3];
- sds str_addr=cmd->argv[4];
+ sds str_state = cmd->argv[3];
+ sds str_addr = cmd->argv[4];
- int ret_string2node=0;
- if(0==strcasecmp(str_state, "IMPORTING"))
+ int ret_string2node = 0;
+ if (0 == strcasecmp(str_state, "IMPORTING"))
{
- state=STATE_IMPORTING;
+ state = STATE_IMPORTING;
}
- else if(0==strcasecmp(str_state, "MIGRATING"))
+ else if (0 == strcasecmp(str_state, "MIGRATING"))
{
- state=STATE_MIGRATING;
+ state = STATE_MIGRATING;
}
- else if(0==strcasecmp(str_state, "NODE"))
+ else if (0 == strcasecmp(str_state, "NODE"))
{
- state=STATE_STABLE;
+ state = STATE_STABLE;
}
- else if(0==strcasecmp(str_state, "STABLE"))
+ else if (0 == strcasecmp(str_state, "STABLE"))
{
- state=STATE_STABLE;
-
+ state = STATE_STABLE;
}
else
{
- *reply=swarmkv_reply_new_error(error_arg_string_should_be, str_state, "IMPORTING|MIGRATING|NODE|STABLE");
+ *reply = swarmkv_reply_new_error(error_arg_string_should_be, str_state, "IMPORTING|MIGRATING|NODE|STABLE");
return FINISHED;
}
- if(state!=STATE_STABLE)
+ if (state != STATE_STABLE)
{
- if(cmd->argc<5)
+ if (cmd->argc < 5)
{
- *reply=swarmkv_reply_new_error(error_need_additional_arg, str_state);
+ *reply = swarmkv_reply_new_error(error_need_additional_arg, str_state);
return FINISHED;
}
- ret_string2node=node_init_from_sds(&peer_node, str_addr);
- if(ret_string2node!=0)
+ ret_string2node = node_init_from_sds(&peer_node, str_addr);
+ if (ret_string2node != 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_address, str_state);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_address, str_state);
return FINISHED;
}
}
- struct slot_runtime *slot_rt=NULL;
- long long slot_id=-1;
- if(0!=str2integer(cmd->argv[2], &slot_id) || slot_id>=KEYSPACE_SLOT_NUM)
+ struct slot_runtime *slot_rt = NULL;
+ long long slot_id = -1;
+ if (0 != str2integer(cmd->argv[2], &slot_id) || slot_id >= KEYSPACE_SLOT_NUM)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
return FINISHED;
}
- slot_rt=&(ks->slot_rts[slot_id]);
-
- slot_rt->state=state;
- if(state!=STATE_STABLE)
+ slot_rt = &(ks->slot_rts[slot_id]);
+
+ slot_rt->state = state;
+ if (state != STATE_STABLE)
{
node_copy(&slot_rt->rebalancing_peer, &peer_node);
}
- *reply=swarmkv_reply_new_status("OK");
+ *reply = swarmkv_reply_new_status("OK");
return FINISHED;
-
}
static void key_entry_serialize(struct key_route_entry *key_entry, char **blob, size_t *blob_sz)
{
- char *mpack_buff=NULL;
- size_t mpack_sz=0;
+ char *mpack_buff = NULL;
+ size_t mpack_sz = 0;
mpack_writer_t writer;
mpack_writer_init_growable(&writer, &mpack_buff, &mpack_sz);
mpack_build_map(&writer);
-
+
mpack_write_cstr(&writer, "timeout");
mpack_write_u64(&writer, key_entry->abs_timeout);
mpack_write_cstr(&writer, "replicas");
- mpack_build_array(&writer);
- struct replica_node *replica=NULL, *tmp=NULL;
+ mpack_build_array(&writer);
+ struct replica_node *replica = NULL, *tmp = NULL;
HASH_ITER(hh, key_entry->hash_replica, replica, tmp)
{
mpack_write_cstr(&writer, replica->node.addr);
- }
+ }
mpack_complete_array(&writer);
-
+
mpack_complete_map(&writer);
mpack_writer_destroy(&writer);
- *blob=mpack_buff;
- *blob_sz=mpack_sz;
+ *blob = mpack_buff;
+ *blob_sz = mpack_sz;
return;
}
static void key_entry_merge(struct key_route_entry *key_entry, const char *blob, size_t blob_sz)
@@ -1326,21 +1307,21 @@ static void key_entry_merge(struct key_route_entry *key_entry, const char *blob,
mpack_tree_t tree;
mpack_tree_init_data(&tree, blob, blob_sz);
mpack_tree_parse(&tree);
- mpack_node_t root=mpack_tree_root(&tree);
+ mpack_node_t root = mpack_tree_root(&tree);
mpack_node_t mpnode_replicas, mpnode_a_replica;
node_t replica;
- key_entry->abs_timeout=mpack_node_u64(mpack_node_map_cstr(root, "timeout"));
- mpnode_replicas=mpack_node_map_cstr(root, "replicas");
-
- size_t n_replica=mpack_node_array_length(mpnode_replicas);
- for(size_t i=0; i<n_replica; i++)
- {
- mpnode_a_replica=mpack_node_array_at(mpnode_replicas, i);
- memset(&replica, 0, sizeof(node_t));
+ key_entry->abs_timeout = mpack_node_u64(mpack_node_map_cstr(root, "timeout"));
+ mpnode_replicas = mpack_node_map_cstr(root, "replicas");
+
+ size_t n_replica = mpack_node_array_length(mpnode_replicas);
+ for (size_t i = 0; i < n_replica; i++)
+ {
+ mpnode_a_replica = mpack_node_array_at(mpnode_replicas, i);
+ memset(&replica, 0, sizeof(node_t));
mpack_node_copy_cstr(mpnode_a_replica, replica.addr, sizeof(replica.addr));
key_entry_add_replica_node(key_entry, &replica);
}
- if(mpack_tree_destroy(&tree)!= mpack_ok)
+ if (mpack_tree_destroy(&tree) != mpack_ok)
{
assert(0);
}
@@ -1349,12 +1330,11 @@ static void key_entry_merge(struct key_route_entry *key_entry, const char *blob,
static void key_slot_serialize(const struct slot_runtime *slot_rt, char **blob, size_t *blob_sz)
{
mpack_writer_t writer;
- char *mpack_buff=NULL;
- size_t mpack_sz=0;
- struct key_route_entry *key_entry=NULL, *tmp_entry=NULL;
- char *keyentry_blob=NULL;
- size_t keyentry_blob_sz=0;
-
+ char *mpack_buff = NULL;
+ size_t mpack_sz = 0;
+ struct key_route_entry *key_entry = NULL, *tmp_entry = NULL;
+ char *keyentry_blob = NULL;
+ size_t keyentry_blob_sz = 0;
mpack_writer_init_growable(&writer, &mpack_buff, &mpack_sz);
mpack_build_map(&writer);
@@ -1362,22 +1342,21 @@ static void key_slot_serialize(const struct slot_runtime *slot_rt, char **blob,
mpack_write_cstr(&writer, "slot_id");
mpack_write_int(&writer, slot_rt->slot.slot_id);
-
- mpack_write_cstr(&writer, "key_route_table");
+ mpack_write_cstr(&writer, "key_route_table");
mpack_build_array(&writer);
HASH_ITER(hh, slot_rt->keyroute_table, key_entry, tmp_entry)
- {
+ {
mpack_write_str(&writer, key_entry->key, sdslen(key_entry->key));
key_entry_serialize(key_entry, &keyentry_blob, &keyentry_blob_sz);
mpack_write_str(&writer, keyentry_blob, keyentry_blob_sz);
free(keyentry_blob);
- keyentry_blob_sz=0;
+ keyentry_blob_sz = 0;
}
mpack_complete_array(&writer);
mpack_complete_map(&writer);
mpack_writer_destroy(&writer);
- *blob=mpack_buff;
- *blob_sz=mpack_sz;
+ *blob = mpack_buff;
+ *blob_sz = mpack_sz;
return;
}
long long key_slot_merge(struct slot_runtime *slot_rt, const char *blob, size_t blob_sz, struct timeouts *expires)
@@ -1385,126 +1364,125 @@ long long key_slot_merge(struct slot_runtime *slot_rt, const char *blob, size_t
mpack_tree_t tree;
mpack_tree_init_data(&tree, blob, blob_sz);
mpack_tree_parse(&tree);
- mpack_node_t root=mpack_tree_root(&tree);
+ mpack_node_t root = mpack_tree_root(&tree);
mpack_node_t mpnode_key, mpnode_keyentry, mpnode_table;
- int __attribute__((__unused__))slot_id=mpack_node_int(mpack_node_map_cstr(root, "slot_id"));
- assert(slot_id==slot_rt->slot.slot_id);
- mpnode_table=mpack_node_map_cstr(root, "key_route_table");
-
- long long new_added_entry_num=0;
-
- size_t entry_num=mpack_node_array_length(mpnode_table);
- struct key_route_entry *key_entry=NULL;
-
- for(size_t i=0; i<entry_num; i+=2)
- {
- mpnode_key=mpack_node_array_at(mpnode_table, i);
- mpnode_keyentry=mpack_node_array_at(mpnode_table, i+1);
+ int __attribute__((__unused__)) slot_id = mpack_node_int(mpack_node_map_cstr(root, "slot_id"));
+ assert(slot_id == slot_rt->slot.slot_id);
+ mpnode_table = mpack_node_map_cstr(root, "key_route_table");
+
+ long long new_added_entry_num = 0;
+
+ size_t entry_num = mpack_node_array_length(mpnode_table);
+ struct key_route_entry *key_entry = NULL;
+
+ for (size_t i = 0; i < entry_num; i += 2)
+ {
+ mpnode_key = mpack_node_array_at(mpnode_table, i);
+ mpnode_keyentry = mpack_node_array_at(mpnode_table, i + 1);
HASH_FIND(hh, slot_rt->keyroute_table, mpack_node_str(mpnode_key), mpack_node_strlen(mpnode_key), key_entry);
- if(!key_entry)
+ if (!key_entry)
{
- key_entry=key_entry_new_len(mpack_node_str(mpnode_key), mpack_node_strlen(mpnode_key));
+ key_entry = key_entry_new_len(mpack_node_str(mpnode_key), mpack_node_strlen(mpnode_key));
HASH_ADD_KEYPTR(hh, slot_rt->keyroute_table, key_entry->key, sdslen(key_entry->key), key_entry);
new_added_entry_num++;
}
key_entry_merge(key_entry, mpack_node_str(mpnode_keyentry), mpack_node_strlen(mpnode_keyentry));
- if(key_entry->is_expiring)
+ if (key_entry->is_expiring)
{
timeouts_del(expires, &key_entry->timeout_handle);
}
- if(key_entry->abs_timeout)
+ if (key_entry->abs_timeout)
{
timeout_init(&key_entry->timeout_handle, TIMEOUT_ABS);
- key_entry->is_expiring=1;
- timeouts_add(expires, &key_entry->timeout_handle, key_entry->abs_timeout);
+ key_entry->is_expiring = 1;
+ timeouts_add(expires, &key_entry->timeout_handle, key_entry->abs_timeout);
}
}
- if(mpack_tree_destroy(&tree)!= mpack_ok)
+ if (mpack_tree_destroy(&tree) != mpack_ok)
{
assert(0);
}
return new_added_entry_num;
}
-enum cmd_exec_result keyspace_getkeysinslot_command(struct swarmkv_module *mod_keyspace, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
+enum cmd_exec_result keyspace_getkeysinslot_command(struct swarmkv_module *mod_keyspace, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* KEYSPACE GETKEYSINSLOT slot */
+ /* KEYSPACE GETKEYSINSLOT slot */
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- long long slot_id=-1;
- struct slot_runtime *slot_rt=NULL;
- if(0!=str2integer(cmd->argv[2], &slot_id) || slot_id>=KEYSPACE_SLOT_NUM)
+ long long slot_id = -1;
+ struct slot_runtime *slot_rt = NULL;
+ if (0 != str2integer(cmd->argv[2], &slot_id) || slot_id >= KEYSPACE_SLOT_NUM)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
return FINISHED;
}
- slot_rt=ks->slot_rts+slot_id;
- char *blob=NULL;
+ slot_rt = ks->slot_rts + slot_id;
+ char *blob = NULL;
size_t blob_sz;
key_slot_serialize(slot_rt, &blob, &blob_sz);
- *reply=swarmkv_reply_new_string(blob, blob_sz);
+ *reply = swarmkv_reply_new_string(blob, blob_sz);
free(blob);
- blob=NULL;
+ blob = NULL;
return FINISHED;
}
static int ks_get_tid(struct swarmkv_keyspace *ks, int slot_id)
{
- int tid=swarmkv_keyspace_slot2tid(&ks->module, slot_id);
- int real_tid=swarmkv_gettid(ks->exec_cmd_handle);
- assert(tid==real_tid);
+ int tid = swarmkv_keyspace_slot2tid(&ks->module, slot_id);
+ int real_tid = swarmkv_gettid(ks->exec_cmd_handle);
+ assert(tid == real_tid);
return tid;
}
enum cmd_exec_result keyspace_addkeystoslot_command(struct swarmkv_module *mod_keyspace, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* KEYSPACE ADDKEYSTOSLOT slot blob */
+ /* KEYSPACE ADDKEYSTOSLOT slot blob */
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- long long slot_id=-1;
- long long new_added_entry_num=0;
- struct slot_runtime *slot_rt=NULL;
+ long long slot_id = -1;
+ long long new_added_entry_num = 0;
+ struct slot_runtime *slot_rt = NULL;
- const sds blob=cmd->argv[3];
+ const sds blob = cmd->argv[3];
- if(0!=str2integer(cmd->argv[2], &slot_id) || slot_id>=KEYSPACE_SLOT_NUM)
+ if (0 != str2integer(cmd->argv[2], &slot_id) || slot_id >= KEYSPACE_SLOT_NUM)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
return FINISHED;
}
- int tid=ks_get_tid(ks, slot_id);
+ int tid = ks_get_tid(ks, slot_id);
- slot_rt=ks->slot_rts+slot_id;
-
- new_added_entry_num=key_slot_merge(slot_rt, blob, sdslen(blob), ks->threads[tid].expires);
+ slot_rt = ks->slot_rts + slot_id;
+ new_added_entry_num = key_slot_merge(slot_rt, blob, sdslen(blob), ks->threads[tid].expires);
- *reply=swarmkv_reply_new_integer(new_added_entry_num);
+ *reply = swarmkv_reply_new_integer(new_added_entry_num);
return FINISHED;
}
enum cmd_exec_result keyspace_delslotkeys_command(struct swarmkv_module *mod_keyspace, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* KEYSPACE DELSLOTKEYS slot */
+ /* KEYSPACE DELSLOTKEYS slot */
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- long long slot_id=-1;
- struct slot_runtime *slot_rt=NULL;
- struct key_route_entry *key_entry=NULL, *tmp=NULL;
- long long delete_num=0;
+ long long slot_id = -1;
+ struct slot_runtime *slot_rt = NULL;
+ struct key_route_entry *key_entry = NULL, *tmp = NULL;
+ long long delete_num = 0;
- if(0!=str2integer(cmd->argv[2], &slot_id) || slot_id>=KEYSPACE_SLOT_NUM)
+ if (0 != str2integer(cmd->argv[2], &slot_id) || slot_id >= KEYSPACE_SLOT_NUM)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
return FINISHED;
}
- int tid=ks_get_tid(ks, slot_id);
- slot_rt=ks->slot_rts+slot_id;
- struct ks_thread *thr=ks->threads+tid;
+ int tid = ks_get_tid(ks, slot_id);
+ slot_rt = ks->slot_rts + slot_id;
+ struct ks_thread *thr = ks->threads + tid;
HASH_ITER(hh, slot_rt->keyroute_table, key_entry, tmp)
{
HASH_DELETE(hh, slot_rt->keyroute_table, key_entry);
- if(key_entry->is_expiring)
+ if (key_entry->is_expiring)
{
timeouts_del(thr->expires, &key_entry->timeout_handle);
}
@@ -1512,28 +1490,28 @@ enum cmd_exec_result keyspace_delslotkeys_command(struct swarmkv_module *mod_key
delete_num++;
}
- *reply=swarmkv_reply_new_integer(delete_num);
+ *reply = swarmkv_reply_new_integer(delete_num);
return FINISHED;
}
enum cmd_exec_result keyspace_countkeysinslot_command(struct swarmkv_module *mod_keyspace, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*KEYSPACE COUNTKEYSINSLOT slot*/
+ /*KEYSPACE COUNTKEYSINSLOT slot*/
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- long long slot_id=-1;
- struct slot_runtime* slot_rt=NULL;
- long long key_num=0;
+ long long slot_id = -1;
+ struct slot_runtime *slot_rt = NULL;
+ long long key_num = 0;
- if(0!=str2integer(cmd->argv[2], &slot_id) || slot_id>=KEYSPACE_SLOT_NUM)
+ if (0 != str2integer(cmd->argv[2], &slot_id) || slot_id >= KEYSPACE_SLOT_NUM)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
return FINISHED;
}
- slot_rt=ks->slot_rts+slot_id;
+ slot_rt = ks->slot_rts + slot_id;
- key_num=HASH_COUNT(slot_rt->keyroute_table);
+ key_num = HASH_COUNT(slot_rt->keyroute_table);
- *reply=swarmkv_reply_new_integer(key_num);
+ *reply = swarmkv_reply_new_integer(key_num);
return FINISHED;
}
enum KEYSPACE_OP
@@ -1542,101 +1520,101 @@ enum KEYSPACE_OP
KEYSPACE_RADD,
KEYSPACE_XRADD,
KEYSPACE_DEL,
- KEYSPACE_RDEL,
+ KEYSPACE_RDEL,
KEYSPACE_EXISTS
};
enum cmd_exec_result key_route_generic(struct swarmkv_keyspace *ks, enum KEYSPACE_OP op, const sds key, const node_t *new_replica, struct swarmkv_reply **reply)
{
- struct key_route_entry *key_entry=NULL;
- int slot_id=-1;
- struct slot_runtime *slot_rt=NULL;
+ struct key_route_entry *key_entry = NULL;
+ int slot_id = -1;
+ struct slot_runtime *slot_rt = NULL;
- slot_id=key_hash_slot(key, sdslen(key));
- slot_rt=ks->slot_rts+slot_id;
- if(node_compare(&slot_rt->slot.owner, &ks->self) && slot_rt->state!=STATE_IMPORTING)
+ slot_id = key_hash_slot(key, sdslen(key));
+ slot_rt = ks->slot_rts + slot_id;
+ if (node_compare(&slot_rt->slot.owner, &ks->self) && slot_rt->state != STATE_IMPORTING)
{
- *reply=swarmkv_reply_new_node(&(slot_rt->slot.owner), 1);
+ *reply = swarmkv_reply_new_node(&(slot_rt->slot.owner), 1);
return REDIRECT;
}
-
+
HASH_FIND(hh, slot_rt->keyroute_table, key, sdslen(key), key_entry);
- if(!key_entry && slot_rt->state==STATE_MIGRATING)
+ if (!key_entry && slot_rt->state == STATE_MIGRATING)
{
- *reply=swarmkv_reply_new_node(&(slot_rt->rebalancing_peer), 1);
+ *reply = swarmkv_reply_new_node(&(slot_rt->rebalancing_peer), 1);
return REDIRECT;
}
- switch(op)
+ switch (op)
{
- case KEYSPACE_RLIST:
- if(key_entry)
- {
- *reply=key_entry_list_replica_nodes(key_entry);
- }
- else
- {
- *reply=swarmkv_reply_new_nil();
- }
- break;
- case KEYSPACE_RADD:
- if(!key_entry)
- {
- key_entry=key_entry_new(key);
- HASH_ADD_KEYPTR(hh, slot_rt->keyroute_table, key_entry->key, sdslen(key_entry->key), key_entry);
- }
+ case KEYSPACE_RLIST:
+ if (key_entry)
+ {
+ *reply = key_entry_list_replica_nodes(key_entry);
+ }
+ else
+ {
+ *reply = swarmkv_reply_new_nil();
+ }
+ break;
+ case KEYSPACE_RADD:
+ if (!key_entry)
+ {
+ key_entry = key_entry_new(key);
+ HASH_ADD_KEYPTR(hh, slot_rt->keyroute_table, key_entry->key, sdslen(key_entry->key), key_entry);
+ }
+ key_entry_add_replica_node(key_entry, new_replica);
+ key_entry_meet_replica(key_entry, ks->exec_cmd_handle);
+ *reply = key_entry_list_replica_nodes(key_entry);
+ break;
+ case KEYSPACE_XRADD:
+ if (key_entry)
+ {
key_entry_add_replica_node(key_entry, new_replica);
+ *reply = key_entry_list_replica_nodes(key_entry);
key_entry_meet_replica(key_entry, ks->exec_cmd_handle);
- *reply=key_entry_list_replica_nodes(key_entry);
- break;
- case KEYSPACE_XRADD:
- if(key_entry)
- {
- key_entry_add_replica_node(key_entry, new_replica);
- *reply=key_entry_list_replica_nodes(key_entry);
- key_entry_meet_replica(key_entry, ks->exec_cmd_handle);
- }
- else
- {
- *reply=swarmkv_reply_new_nil();
- }
- break;
- case KEYSPACE_DEL:
- if(key_entry)
+ }
+ else
+ {
+ *reply = swarmkv_reply_new_nil();
+ }
+ break;
+ case KEYSPACE_DEL:
+ if (key_entry)
+ {
+ HASH_DELETE(hh, slot_rt->keyroute_table, key_entry);
+ key_entry_deletion_notification(key_entry, ks->exec_cmd_handle);
+ key_entry_free(key_entry);
+ *reply = swarmkv_reply_new_integer(1);
+ }
+ else
+ {
+ *reply = swarmkv_reply_new_integer(0);
+ }
+ break;
+ case KEYSPACE_RDEL:
+ if (key_entry)
+ {
+ size_t n_existed_replica = 0;
+ key_entry_rdel_replica_node(key_entry, new_replica);
+ n_existed_replica = HASH_COUNT(key_entry->hash_replica);
+ if (n_existed_replica == 0)
{
HASH_DELETE(hh, slot_rt->keyroute_table, key_entry);
- key_entry_deletion_notification(key_entry, ks->exec_cmd_handle);
- key_entry_free(key_entry);
- *reply=swarmkv_reply_new_integer(1);
}
- else
- {
- *reply=swarmkv_reply_new_integer(0);
- }
- break;
- case KEYSPACE_RDEL:
- if(key_entry)
- {
- size_t n_existed_replica=0;
- key_entry_rdel_replica_node(key_entry, new_replica);
- n_existed_replica=HASH_COUNT(key_entry->hash_replica);
- if(n_existed_replica==0)
- {
- HASH_DELETE(hh, slot_rt->keyroute_table, key_entry);
- }
- *reply=swarmkv_reply_new_integer(1);
- }
- else
- {
- *reply=swarmkv_reply_new_integer(0);
- }
- break;
- case KEYSPACE_EXISTS:
- *reply=swarmkv_reply_new_integer(key_entry?1:0);
- break;
- default:
- assert(0);
- break;
+ *reply = swarmkv_reply_new_integer(1);
+ }
+ else
+ {
+ *reply = swarmkv_reply_new_integer(0);
+ }
+ break;
+ case KEYSPACE_EXISTS:
+ *reply = swarmkv_reply_new_integer(key_entry ? 1 : 0);
+ break;
+ default:
+ assert(0);
+ break;
}
return FINISHED;
}
@@ -1644,82 +1622,82 @@ enum cmd_exec_result key_route_generic(struct swarmkv_keyspace *ks, enum KEYSPAC
UT_icd ut_swarmkv_reply_pointer_icd = {sizeof(struct swarmkv_reply *), NULL, NULL, NULL};
enum cmd_exec_result keyspace_keys_command(struct swarmkv_module *mod_keyspace, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* KEYSPACE KEYS tid pattern */
+ /* KEYSPACE KEYS tid pattern */
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- size_t i=0, n_matched=0;
- struct slot_runtime *slot_rt=NULL;
- struct key_route_entry *key_entry=NULL, *tmp=NULL;
- int is_matched=0;
- UT_array *matched_replies=NULL;
- struct swarmkv_reply *r=NULL;
- int real_tid=swarmkv_gettid(ks->exec_cmd_handle);
- int thread_id=atoll(cmd->argv[2]);
- assert(real_tid==thread_id);
- const sds pattern=cmd->argv[3];
+ size_t i = 0, n_matched = 0;
+ struct slot_runtime *slot_rt = NULL;
+ struct key_route_entry *key_entry = NULL, *tmp = NULL;
+ int is_matched = 0;
+ UT_array *matched_replies = NULL;
+ struct swarmkv_reply *r = NULL;
+ int real_tid = swarmkv_gettid(ks->exec_cmd_handle);
+ int thread_id = atoll(cmd->argv[2]);
+ assert(real_tid == thread_id);
+ const sds pattern = cmd->argv[3];
utarray_new(matched_replies, &ut_swarmkv_reply_pointer_icd);
- for(i=0; i<KEYSPACE_SLOT_NUM; i++)
+ for (i = 0; i < KEYSPACE_SLOT_NUM; i++)
{
- slot_rt=ks->slot_rts+i;
- if(node_compare(&slot_rt->slot.owner, &ks->self) && slot_rt->state!=STATE_IMPORTING)
+ slot_rt = ks->slot_rts + i;
+ if (node_compare(&slot_rt->slot.owner, &ks->self) && slot_rt->state != STATE_IMPORTING)
{
continue;
}
- if(!slot_is_my_thread(i, thread_id, ks->opts->nr_worker_threads))
+ if (!slot_is_my_thread(i, thread_id, ks->opts->nr_worker_threads))
{
continue;
}
HASH_ITER(hh, slot_rt->keyroute_table, key_entry, tmp)
{
- is_matched=stringmatchlen(pattern, sdslen(pattern), key_entry->key, sdslen(key_entry->key), 0);
- if(is_matched)
+ is_matched = stringmatchlen(pattern, sdslen(pattern), key_entry->key, sdslen(key_entry->key), 0);
+ if (is_matched)
{
- r=swarmkv_reply_new_string(key_entry->key, sdslen(key_entry->key));
+ r = swarmkv_reply_new_string(key_entry->key, sdslen(key_entry->key));
utarray_push_back(matched_replies, &r);
}
}
}
- n_matched=utarray_len(matched_replies);
- if(n_matched>0)
+ n_matched = utarray_len(matched_replies);
+ if (n_matched > 0)
{
- *reply=swarmkv_reply_new_array(n_matched);
- for(i=0; i<n_matched; i++)
+ *reply = swarmkv_reply_new_array(n_matched);
+ for (i = 0; i < n_matched; i++)
{
- (*reply)->elements[i]=*(struct swarmkv_reply **)utarray_eltptr(matched_replies, i);
+ (*reply)->elements[i] = *(struct swarmkv_reply **)utarray_eltptr(matched_replies, i);
}
}
else
{
- *reply=swarmkv_reply_new_nil();
+ *reply = swarmkv_reply_new_nil();
}
utarray_free(matched_replies);
- matched_replies=NULL;
+ matched_replies = NULL;
return FINISHED;
}
enum cmd_exec_result keyspace_rlist_command(struct swarmkv_module *mod_keyspace, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*KEYSPACE RLIST <key> */
+ /*KEYSPACE RLIST <key> */
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- enum cmd_exec_result ret=FINISHED;
- sds key=cmd->argv[2];
-
- ret=key_route_generic(ks, KEYSPACE_RLIST, key, NULL, reply);
+ enum cmd_exec_result ret = FINISHED;
+ sds key = cmd->argv[2];
+
+ ret = key_route_generic(ks, KEYSPACE_RLIST, key, NULL, reply);
return ret;
}
enum cmd_exec_result keyspace_radd_command(struct swarmkv_module *mod_keyspace, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*KEYSPACE RADD <key> IP:port*/
+ /*KEYSPACE RADD <key> IP:port*/
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- enum cmd_exec_result ret=FINISHED;
- sds key=cmd->argv[2];
+ enum cmd_exec_result ret = FINISHED;
+ sds key = cmd->argv[2];
node_t new_replica;
- if(cmd->argc==4)
+ if (cmd->argc == 4)
{
- if(0>node_init_from_sds(&new_replica, cmd->argv[3]))
+ if (0 > node_init_from_sds(&new_replica, cmd->argv[3]))
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_address, cmd->argv+3);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_address, cmd->argv + 3);
return ret;
}
}
@@ -1727,59 +1705,59 @@ enum cmd_exec_result keyspace_radd_command(struct swarmkv_module *mod_keyspace,
{
node_copy(&new_replica, &ks->self);
}
- ret=key_route_generic(ks, KEYSPACE_RADD, key, &new_replica, reply);
+ ret = key_route_generic(ks, KEYSPACE_RADD, key, &new_replica, reply);
return ret;
}
enum cmd_exec_result keyspace_xradd_command(struct swarmkv_module *mod_keyspace, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*KEYSPACE XRADD <key> IP:port*/
+ /*KEYSPACE XRADD <key> IP:port*/
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- enum cmd_exec_result ret=FINISHED;
- sds key=cmd->argv[2];
-
+ enum cmd_exec_result ret = FINISHED;
+ sds key = cmd->argv[2];
+
node_t new_replica;
- if(0>node_init_from_sds(&new_replica, cmd->argv[3]))
+ if (0 > node_init_from_sds(&new_replica, cmd->argv[3]))
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_address, cmd->argv+3);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_address, cmd->argv + 3);
return ret;
}
- ret=key_route_generic(ks, KEYSPACE_XRADD, key, &new_replica, reply);
+ ret = key_route_generic(ks, KEYSPACE_XRADD, key, &new_replica, reply);
return ret;
}
enum cmd_exec_result keyspace_exists_command(struct swarmkv_module *mod_keyspace, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*KEYSPACE EXISTS <key>*/
+ /*KEYSPACE EXISTS <key>*/
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- enum cmd_exec_result ret=FINISHED;
- sds key=cmd->argv[2];
-
- ret=key_route_generic(ks, KEYSPACE_EXISTS, key, NULL, reply);
+ enum cmd_exec_result ret = FINISHED;
+ sds key = cmd->argv[2];
+
+ ret = key_route_generic(ks, KEYSPACE_EXISTS, key, NULL, reply);
return ret;
}
enum cmd_exec_result del_command(struct swarmkv_module *mod_keyspace, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*DEL <key> */
+ /*DEL <key> */
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- enum cmd_exec_result ret=FINISHED;
- sds key=cmd->argv[1];
- ret=key_route_generic(ks, KEYSPACE_DEL, key, NULL, reply);
+ enum cmd_exec_result ret = FINISHED;
+ sds key = cmd->argv[1];
+ ret = key_route_generic(ks, KEYSPACE_DEL, key, NULL, reply);
return ret;
}
enum cmd_exec_result keyspace_rdel_command(struct swarmkv_module *mod_keyspace, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*KEYSPACE RDEL <key IP:port> */
+ /*KEYSPACE RDEL <key IP:port> */
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- enum cmd_exec_result ret=FINISHED;
- sds key=cmd->argv[2];
+ enum cmd_exec_result ret = FINISHED;
+ sds key = cmd->argv[2];
- node_t del_replica;
- if(0>node_init_from_sds(&del_replica, cmd->argv[3]))
+ node_t del_replica;
+ if (0 > node_init_from_sds(&del_replica, cmd->argv[3]))
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_address, cmd->argv+3);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_address, cmd->argv + 3);
return ret;
}
- ret=key_route_generic(ks, KEYSPACE_RDEL, key, &del_replica, reply);
+ ret = key_route_generic(ks, KEYSPACE_RDEL, key, &del_replica, reply);
return ret;
}
@@ -1791,158 +1769,155 @@ enum KEY_TTL_OP
};
enum cmd_exec_result key_ttl_generic(struct swarmkv_keyspace *ks, enum KEY_TTL_OP op, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- const sds key=cmd->argv[1];
- long seconds=0;
- char *endptr=NULL;
+ const sds key = cmd->argv[1];
+ long seconds = 0;
+ char *endptr = NULL;
- enum cmd_exec_result ret=FINISHED;
+ enum cmd_exec_result ret = FINISHED;
- int slot_id=key_hash_slot(key, sdslen(key));
- struct slot_runtime *slot_rt=ks->slot_rts+slot_id;
- struct key_route_entry *key_entry=NULL;
- if(node_compare(&slot_rt->slot.owner, &ks->self) && slot_rt->state != STATE_IMPORTING)
+ int slot_id = key_hash_slot(key, sdslen(key));
+ struct slot_runtime *slot_rt = ks->slot_rts + slot_id;
+ struct key_route_entry *key_entry = NULL;
+ if (node_compare(&slot_rt->slot.owner, &ks->self) && slot_rt->state != STATE_IMPORTING)
{
- *reply=swarmkv_reply_new_node(&(slot_rt->slot.owner), 1);
+ *reply = swarmkv_reply_new_node(&(slot_rt->slot.owner), 1);
return REDIRECT;
}
- int tid=ks_get_tid(ks, slot_id);
- struct ks_thread *thr=ks->threads+tid;
+ int tid = ks_get_tid(ks, slot_id);
+ struct ks_thread *thr = ks->threads + tid;
HASH_FIND(hh, slot_rt->keyroute_table, key, sdslen(key), key_entry);
- if(!key_entry)
+ if (!key_entry)
{
- if(slot_rt->state==STATE_MIGRATING)
+ if (slot_rt->state == STATE_MIGRATING)
{
- *reply=swarmkv_reply_new_node(&(slot_rt->rebalancing_peer), 1);
- ret=REDIRECT;
+ *reply = swarmkv_reply_new_node(&(slot_rt->rebalancing_peer), 1);
+ ret = REDIRECT;
}
else
{
- *reply=swarmkv_reply_new_integer((op==KEY_TTL_SET||op==KEY_TTL_REMOVE)?0:-2);
- ret=FINISHED;
+ *reply = swarmkv_reply_new_integer((op == KEY_TTL_SET || op == KEY_TTL_REMOVE) ? 0 : -2);
+ ret = FINISHED;
}
return ret;
}
struct timespec now;
clock_gettime(CLOCK_REALTIME, &now);
- switch(op)
+ switch (op)
{
- case KEY_TTL_SET:
+ case KEY_TTL_SET:
- seconds=strtol(cmd->argv[2], &endptr, 10);
- if(*endptr!='\0' || seconds>INT_MAX)
- {
- *reply=swarmkv_reply_new_error(error_value_not_integer);
- }
- else
- {
- if(key_entry->is_expiring)
- {
- timeouts_del(thr->expires, &key_entry->timeout_handle);
- }
- timeout_init(&key_entry->timeout_handle, TIMEOUT_ABS);
- key_entry->is_expiring=1;
- key_entry->abs_timeout=now.tv_sec+seconds;
- timeouts_add(thr->expires, &key_entry->timeout_handle, key_entry->abs_timeout);
- *reply=swarmkv_reply_new_integer(1);
- }
-
- break;
- case KEY_TTL_GET:
- if(key_entry->is_expiring)
- {
- int ttl=key_entry->abs_timeout - now.tv_sec;
- *reply=swarmkv_reply_new_integer(ttl);
- }
- else
- {
- *reply=swarmkv_reply_new_integer(-1);
- }
- break;
- case KEY_TTL_REMOVE:
- if(key_entry->is_expiring)
- {
- timeouts_del(thr->expires, &(key_entry->timeout_handle));
- key_entry->is_expiring=0;
- *reply=swarmkv_reply_new_integer(1);
- }
- else
+ seconds = strtol(cmd->argv[2], &endptr, 10);
+ if (*endptr != '\0' || seconds > INT_MAX)
+ {
+ *reply = swarmkv_reply_new_error(error_value_not_integer);
+ }
+ else
+ {
+ if (key_entry->is_expiring)
{
- *reply=swarmkv_reply_new_integer(0);
+ timeouts_del(thr->expires, &key_entry->timeout_handle);
}
- break;
- default:
- assert(0);
- break;
+ timeout_init(&key_entry->timeout_handle, TIMEOUT_ABS);
+ key_entry->is_expiring = 1;
+ key_entry->abs_timeout = now.tv_sec + seconds;
+ timeouts_add(thr->expires, &key_entry->timeout_handle, key_entry->abs_timeout);
+ *reply = swarmkv_reply_new_integer(1);
+ }
+
+ break;
+ case KEY_TTL_GET:
+ if (key_entry->is_expiring)
+ {
+ int ttl = key_entry->abs_timeout - now.tv_sec;
+ *reply = swarmkv_reply_new_integer(ttl);
+ }
+ else
+ {
+ *reply = swarmkv_reply_new_integer(-1);
+ }
+ break;
+ case KEY_TTL_REMOVE:
+ if (key_entry->is_expiring)
+ {
+ timeouts_del(thr->expires, &(key_entry->timeout_handle));
+ key_entry->is_expiring = 0;
+ *reply = swarmkv_reply_new_integer(1);
+ }
+ else
+ {
+ *reply = swarmkv_reply_new_integer(0);
+ }
+ break;
+ default:
+ assert(0);
+ break;
}
return FINISHED;
}
enum cmd_exec_result expire_command(struct swarmkv_module *mod_keyspace, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* EXPIRE key seconds */
- enum cmd_exec_result ret=0;
+ /* EXPIRE key seconds */
+ enum cmd_exec_result ret = 0;
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- ret=key_ttl_generic(ks, KEY_TTL_SET, cmd, reply);
+ ret = key_ttl_generic(ks, KEY_TTL_SET, cmd, reply);
return ret;
}
enum cmd_exec_result ttl_command(struct swarmkv_module *mod_keyspace, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* TTL key */
- enum cmd_exec_result ret=0;
+ /* TTL key */
+ enum cmd_exec_result ret = 0;
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- ret=key_ttl_generic(ks, KEY_TTL_GET, cmd, reply);
+ ret = key_ttl_generic(ks, KEY_TTL_GET, cmd, reply);
return ret;
}
enum cmd_exec_result persist_command(struct swarmkv_module *mod_keyspace, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* PERSIST key */
- enum cmd_exec_result ret=0;
+ /* PERSIST key */
+ enum cmd_exec_result ret = 0;
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- ret=key_ttl_generic(ks, KEY_TTL_REMOVE, cmd, reply);
+ ret = key_ttl_generic(ks, KEY_TTL_REMOVE, cmd, reply);
return ret;
-
}
int swarmkv_keyspace_slot2tid(struct swarmkv_module *mod_keyspace, int slot_id)
{
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- return slot_id%ks->opts->nr_worker_threads;
+ return slot_id % ks->opts->nr_worker_threads;
}
#define ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP 1000
void swarmkv_keyspace_periodic(struct swarmkv_module *mod_keyspace, int thread_id)
{
struct swarmkv_keyspace *ks = module2keyspace(mod_keyspace);
- int real_tid=swarmkv_gettid(ks->exec_cmd_handle);
- assert(real_tid==thread_id);
- struct ks_thread *thr=ks->threads+thread_id;
-
- int i=0;
- struct slot_runtime *slot_rt=NULL;
- struct timeout *t=NULL;
- struct key_route_entry *key_entry=NULL;
+ int real_tid = swarmkv_gettid(ks->exec_cmd_handle);
+ assert(real_tid == thread_id);
+ struct ks_thread *thr = ks->threads + thread_id;
+
+ int i = 0;
+ struct slot_runtime *slot_rt = NULL;
+ struct timeout *t = NULL;
+ struct key_route_entry *key_entry = NULL;
struct timespec start, end, now;
- int has_key_expired=0;
+ int has_key_expired = 0;
clock_gettime(CLOCK_MONOTONIC_COARSE, &start);
clock_gettime(CLOCK_REALTIME, &now);
-
timeouts_update(thr->expires, now.tv_sec);
- t=timeouts_get(thr->expires);
- while(t && i<ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP)
+ t = timeouts_get(thr->expires);
+ while (t && i < ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP)
{
- key_entry=container_of(t, struct key_route_entry, timeout_handle);
+ key_entry = container_of(t, struct key_route_entry, timeout_handle);
assert(key_entry->is_expiring);
- slot_rt=ks->slot_rts+key_hash_slot(key_entry->key, sdslen(key_entry->key));
+ slot_rt = ks->slot_rts + key_hash_slot(key_entry->key, sdslen(key_entry->key));
HASH_DELETE(hh, slot_rt->keyroute_table, key_entry);
key_entry_deletion_notification(key_entry, ks->exec_cmd_handle);
key_entry_free(key_entry);
- t=timeouts_get(thr->expires);
+ t = timeouts_get(thr->expires);
i++;
- has_key_expired=1;
+ has_key_expired = 1;
}
-
+
clock_gettime(CLOCK_MONOTONIC_COARSE, &end);
- if(has_key_expired)
+ if (has_key_expired)
{
swarmkv_monitor_record_event(ks->mod_monitor, "keyspace-expire-cycle", timespec_diff_usec(&start, &end));
}
}
-
diff --git a/src/swarmkv_mesh.c b/src/swarmkv_mesh.c
index 62d6129..ec32ff8 100644
--- a/src/swarmkv_mesh.c
+++ b/src/swarmkv_mesh.c
@@ -8,19 +8,19 @@
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
-#include <stdint.h> /* Definition of uint64_t */
+#include <stdint.h> /* Definition of uint64_t */
#include <assert.h>
#include <string.h>
-#include <pthread.h> //sanity check
+#include <pthread.h> //sanity check
-#define MODULE_SWAMRKV_MESH module_name_str("swarmkv.mesh")
-#define RINGBUF_SIZE 8*16*1024
+#define MODULE_SWAMRKV_MESH module_name_str("swarmkv.mesh")
+#define RINGBUF_SIZE 8 * 16 * 1024
struct swarmkv_mesh_thread
{
int thread_id;
int efd;
- struct event * ev;
+ struct event *ev;
ringbuf_t *ring;
char *buff;
ringbuf_worker_t **workers;
@@ -33,39 +33,48 @@ struct swarmkv_mesh
size_t nr_thread;
struct swarmkv_mesh_thread *threads;
struct log_handle *ref_logger;
- on_msg_callback_t *on_msg_cb_func;
+ on_mesh_msg_callback_t *on_msg_cb_func;
void *on_msg_cb_arg;
long long drop_msgs;
long long n_void_consume;
};
+struct swarmkv_mesh_header
+{
+ int src_tid;
+ int pad;
+ struct swarmkv_msg *msg;
+};
int swarmkv_mesh_send(struct swarmkv_mesh *mesh, int current_thread_id, int dest_thread_id, struct swarmkv_msg *msg)
{
- assert(current_thread_id<mesh->nr_thread);
+ assert(current_thread_id < mesh->nr_thread);
assert(current_thread_id != dest_thread_id);
- struct swarmkv_mesh_thread *curr_thr=mesh->threads+current_thread_id;
- struct swarmkv_mesh_thread *dest_thr=mesh->threads+dest_thread_id;
- int tid=swarmkv_gettid((struct swarmkv *)(mesh->on_msg_cb_arg));
- assert(tid==current_thread_id);
- ringbuf_t *dest_ring=dest_thr->ring;
- assert(msg->magic == SWARMKV_MSG_MAGIC);
- ssize_t offset=0;
- int retry=0;
- do{
- offset=ringbuf_acquire(dest_ring, curr_thr->workers[dest_thread_id], sizeof(struct swarmkv_msg*));
+ struct swarmkv_mesh_thread *curr_thr = mesh->threads + current_thread_id;
+ struct swarmkv_mesh_thread *dest_thr = mesh->threads + dest_thread_id;
+ int tid = swarmkv_gettid((struct swarmkv *)(mesh->on_msg_cb_arg));
+ assert(tid == current_thread_id);
+ struct swarmkv_mesh_header hdr;
+ hdr.src_tid = current_thread_id;
+ hdr.msg = msg;
+ ringbuf_t *dest_ring = dest_thr->ring;
+ ssize_t offset = 0;
+ int retry = 0;
+ do
+ {
+ offset = ringbuf_acquire(dest_ring, curr_thr->workers[dest_thread_id], sizeof(struct swarmkv_mesh_header));
retry++;
- }while(offset==-1 && retry<3);
- if(offset == -1)
+ } while (offset == -1 && retry < 3);
+ if (offset == -1)
{
mesh->drop_msgs++;
log_warn(mesh->ref_logger, MODULE_SWAMRKV_MESH, "ringbuf of thread %d is full", dest_thread_id);
goto error_out;
}
- memcpy(dest_thr->buff+offset, &msg, sizeof(struct swarmkv_msg*));
+ memcpy(dest_thr->buff + offset, &hdr, sizeof(struct swarmkv_mesh_header));
ringbuf_produce(dest_ring, curr_thr->workers[dest_thread_id]);
- uint64_t val=1;
- ssize_t ret=0;
- ret=write(dest_thr->efd, &val, sizeof(val));
- if(ret != sizeof(uint64_t))
+ uint64_t val = 1;
+ ssize_t ret = 0;
+ ret = write(dest_thr->efd, &val, sizeof(val));
+ if (ret != sizeof(uint64_t))
{
assert(0);
}
@@ -75,91 +84,92 @@ error_out:
swarmkv_msg_free(msg);
return -1;
}
-void swarmkv_mesh_set_on_msg_cb(struct swarmkv_mesh *mesh, on_msg_callback_t cb_func, void *cb_arg)
+void swarmkv_mesh_set_on_msg_cb(struct swarmkv_mesh *mesh, on_mesh_msg_callback_t cb_func, void *cb_arg)
{
- mesh->on_msg_cb_func=cb_func;
- mesh->on_msg_cb_arg=cb_arg;
+ mesh->on_msg_cb_func = cb_func;
+ mesh->on_msg_cb_arg = cb_arg;
return;
}
-static void mesh_on_eventfd_read_cb(evutil_socket_t fd, short what, void * arg)
+static void mesh_on_eventfd_read_cb(evutil_socket_t fd, short what, void *arg)
{
- struct swarmkv_mesh_thread *thr=(struct swarmkv_mesh_thread*)arg;
- struct swarmkv_mesh *mesh=thr->ref_mesh;
- ringbuf_t *ring=thr->ring;
- uint64_t n_msg=0;
+ struct swarmkv_mesh_thread *thr = (struct swarmkv_mesh_thread *)arg;
+ struct swarmkv_mesh *mesh = thr->ref_mesh;
+ ringbuf_t *ring = thr->ring;
+ uint64_t n_msg = 0;
- int tid=swarmkv_gettid((struct swarmkv *)(mesh->on_msg_cb_arg));
- assert(tid==thr->thread_id);
+ int tid = swarmkv_gettid((struct swarmkv *)(mesh->on_msg_cb_arg));
+ assert(tid == thr->thread_id);
ssize_t s = read(thr->efd, &n_msg, sizeof(uint64_t));
- if(s!=sizeof(uint64_t))
+ if (s != sizeof(uint64_t))
{
assert(0);
}
- size_t offset=0, len=0;
-
- struct swarmkv_msg *msg=NULL;
- int i=0;
- while(i<n_msg)
+ size_t offset = 0, len = 0;
+
+ struct swarmkv_mesh_header *hdr = NULL;
+ int i = 0;
+ while (i < n_msg)
{
- len=ringbuf_consume(ring, &offset);
- if(len==0)
+ len = ringbuf_consume(ring, &offset);
+ if (len == 0)
{
mesh->n_void_consume++;
continue;
}
- //The ringbuf adopts a two-phase write, two concurrent producers may generates gap in the buffer.
- //So it is possible that consumer wakes up, but sees a zero-length message.
- msg=*(struct swarmkv_msg**)(thr->buff+offset);
- assert(msg->magic==SWARMKV_MSG_MAGIC);
- ringbuf_release(ring, sizeof(struct swarmkv_msg*));
- mesh->on_msg_cb_func(msg, mesh->on_msg_cb_arg);
+ // The ringbuf adopts a two-phase write, two concurrent producers may generates gap in the buffer.
+ // So it is possible that consumer wakes up, but sees a zero-length message.
+ hdr = (struct swarmkv_mesh_header *)(thr->buff + offset);
+
+ ringbuf_release(ring, sizeof(struct swarmkv_mesh_header));
+ mesh->on_msg_cb_func(hdr->msg, hdr->src_tid, mesh->on_msg_cb_arg);
thr->dequeue_msgs++;
- offset=0;
+ offset = 0;
i++;
}
return;
}
struct swarmkv_mesh *swarmkv_mesh_new(struct event_base *evbase[], int nthreads, struct log_handle *logger)
{
- struct swarmkv_mesh *mesh=ALLOC(struct swarmkv_mesh, 1);
- mesh->nr_thread=nthreads;
- mesh->ref_logger=logger;
- mesh->threads=ALLOC(struct swarmkv_mesh_thread, nthreads);
- size_t ringbuf_obj_size=0;
+ struct swarmkv_mesh *mesh = ALLOC(struct swarmkv_mesh, 1);
+ mesh->nr_thread = nthreads;
+ mesh->ref_logger = logger;
+ mesh->threads = ALLOC(struct swarmkv_mesh_thread, nthreads);
+ size_t ringbuf_obj_size = 0;
ringbuf_get_sizes(nthreads, &ringbuf_obj_size, NULL);
- for(int i=0; i<mesh->nr_thread; i++)
+ for (int i = 0; i < mesh->nr_thread; i++)
{
- mesh->threads[i].thread_id=i;
- mesh->threads[i].efd=eventfd(0, EFD_NONBLOCK|EFD_CLOEXEC );//EFD_NONBLOCK|EFD_CLOEXEC EFD_SEMAPHORE
- mesh->threads[i].workers=ALLOC(ringbuf_worker_t*, nthreads);
- mesh->threads[i].buff=ALLOC(char, RINGBUF_SIZE);
- mesh->threads[i].ring=malloc(ringbuf_obj_size);
+ mesh->threads[i].thread_id = i;
+ mesh->threads[i].efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); // EFD_NONBLOCK|EFD_CLOEXEC EFD_SEMAPHORE
+ mesh->threads[i].workers = ALLOC(ringbuf_worker_t *, nthreads);
+ mesh->threads[i].buff = ALLOC(char, RINGBUF_SIZE);
+ mesh->threads[i].ring = malloc(ringbuf_obj_size);
ringbuf_setup(mesh->threads[i].ring, nthreads, RINGBUF_SIZE);
- if(mesh->threads[i].efd<0)
+ if (mesh->threads[i].efd < 0)
{
log_fatal(mesh->ref_logger, MODULE_SWAMRKV_MESH, "eventfd() failed: %s", strerror(errno));
assert(0);
}
- mesh->threads[i].ev=event_new(evbase[i], mesh->threads[i].efd, EV_READ|EV_PERSIST, mesh_on_eventfd_read_cb, mesh->threads+i);
- //event_priority_set(mesh->threads[i].ev, 1);
+ mesh->threads[i].ev = event_new(evbase[i], mesh->threads[i].efd, EV_READ | EV_PERSIST, mesh_on_eventfd_read_cb, mesh->threads + i);
+ // event_priority_set(mesh->threads[i].ev, 1);
event_add(mesh->threads[i].ev, NULL);
- mesh->threads[i].ref_mesh=mesh;
- mesh->threads[i].evbase=evbase[i];
+ mesh->threads[i].ref_mesh = mesh;
+ mesh->threads[i].evbase = evbase[i];
}
- for(int i=0; i<mesh->nr_thread; i++)
+ for (int i = 0; i < mesh->nr_thread; i++)
{
- for(int j=0; j<mesh->nr_thread; j++)
+ for (int j = 0; j < mesh->nr_thread; j++)
{
- if(i==j) continue;
- mesh->threads[i].workers[j]=ringbuf_register(mesh->threads[j].ring, i);
+ if (i == j)
+ continue;
+ mesh->threads[i].workers[j] = ringbuf_register(mesh->threads[j].ring, i);
}
}
return mesh;
}
void swarmkv_mesh_free(struct swarmkv_mesh *mesh)
{
- for(int i=0; i<mesh->nr_thread; i++)
+ for (int i = 0; i < mesh->nr_thread; i++)
{
close(mesh->threads[i].efd);
ringbuf_release(mesh->threads[i].ring, RINGBUF_SIZE);
@@ -175,13 +185,13 @@ void swarmkv_mesh_free(struct swarmkv_mesh *mesh)
void swarmkv_mesh_info(struct swarmkv_mesh *mesh, struct mesh_info *info)
{
- //info->queued_msgs=mesh->enqueue_msgs-mesh->dequeue_msgs;
+ // info->queued_msgs=mesh->enqueue_msgs-mesh->dequeue_msgs;
memset(info, 0, sizeof(struct mesh_info));
- for(int i=0; i<mesh->nr_thread; i++)
+ for (int i = 0; i < mesh->nr_thread; i++)
{
- info->queued_msgs+=mesh->threads[i].enqueue_msgs;
- info->queued_msgs-=mesh->threads[i].dequeue_msgs;
+ info->queued_msgs += mesh->threads[i].enqueue_msgs;
+ info->queued_msgs -= mesh->threads[i].dequeue_msgs;
}
- info->enqueue_drops=mesh->drop_msgs;
+ info->enqueue_drops = mesh->drop_msgs;
return;
} \ No newline at end of file
diff --git a/src/swarmkv_mesh.h b/src/swarmkv_mesh.h
index 102fc37..59d1973 100644
--- a/src/swarmkv_mesh.h
+++ b/src/swarmkv_mesh.h
@@ -4,7 +4,9 @@
struct swarmkv_mesh;
//The swarmkv_mesh_send takes the ownership of msg.
int swarmkv_mesh_send(struct swarmkv_mesh *mesh, int current_thread_id, int dest_thread_id, struct swarmkv_msg *msg);
-void swarmkv_mesh_set_on_msg_cb(struct swarmkv_mesh *mesh, on_msg_callback_t *cb_func, void *cb_arg);
+//on_msg_callback_t transfers ownership of msg to the callback function
+typedef void on_mesh_msg_callback_t(struct swarmkv_msg *msg, int src_tid, void *arg);
+void swarmkv_mesh_set_on_msg_cb(struct swarmkv_mesh *mesh, on_mesh_msg_callback_t *cb_func, void *cb_arg);
struct swarmkv_mesh *swarmkv_mesh_new(struct event_base *evbase[], int nthreads, struct log_handle *logger);
void swarmkv_mesh_free(struct swarmkv_mesh *mesh);
struct mesh_info
diff --git a/src/swarmkv_message.c b/src/swarmkv_message.c
index 9798ff0..c134553 100644
--- a/src/swarmkv_message.c
+++ b/src/swarmkv_message.c
@@ -1,54 +1,53 @@
#include "mpack.h"
#include "swarmkv_utils.h"
#include "swarmkv_message.h"
-#include "snappy-c.h"
#include <string.h>
-static struct swarmkv_reply* deserialize_reply(mpack_node_t reply_node)
+static struct swarmkv_reply *deserialize_reply(mpack_node_t reply_node)
{
- struct swarmkv_reply* reply=NULL;
+ struct swarmkv_reply *reply = NULL;
mpack_node_t item, array_node, vtype_item;
- item=mpack_node_map_cstr(reply_node, "t");
- size_t i=0;
- enum swarmkv_reply_type type=mpack_node_int(item);
- switch(type)
+ item = mpack_node_map_cstr(reply_node, "t");
+ size_t i = 0;
+ enum swarmkv_reply_type type = mpack_node_int(item);
+ switch (type)
{
- case SWARMKV_REPLY_INTEGER:
- item=mpack_node_map_cstr(reply_node, "int");
- reply=swarmkv_reply_new_integer(mpack_node_i64(item));
- break;
- case SWARMKV_REPLY_DOUBLE:
- item=mpack_node_map_cstr(reply_node, "dval");
- reply=swarmkv_reply_new_double(mpack_node_double(item));
- break;
- case SWARMKV_REPLY_STRING:
- case SWARMKV_REPLY_ERROR:
- case SWARMKV_REPLY_STATUS:
- case SWARMKV_REPLY_NODE:
- item=mpack_node_map_cstr(reply_node, "str");
- reply=swarmkv_reply_new_string(mpack_node_str(item), mpack_node_strlen(item));
- reply->type=type;//dirty here
- break;
- case SWARMKV_REPLY_VERBATIM:
- item=mpack_node_map_cstr(reply_node, "str");
- vtype_item=mpack_node_map_cstr(reply_node, "vtype");
- reply=swarmkv_reply_new_verbatim(mpack_node_str(item), mpack_node_strlen(item), mpack_node_str(vtype_item));
- break;
- case SWARMKV_REPLY_NIL:
- reply=swarmkv_reply_new_nil();
- break;
- case SWARMKV_REPLY_ARRAY:
- array_node=mpack_node_map_cstr(reply_node, "arr");
- reply=swarmkv_reply_new_array(mpack_node_array_length(array_node));
- for(i=0; i<reply->n_element; i++)
- {
- item=mpack_node_array_at(array_node, i);
- reply->elements[i]=deserialize_reply(item);
- }
- break;
- default:
- assert(0);
- break;
+ case SWARMKV_REPLY_INTEGER:
+ item = mpack_node_map_cstr(reply_node, "int");
+ reply = swarmkv_reply_new_integer(mpack_node_i64(item));
+ break;
+ case SWARMKV_REPLY_DOUBLE:
+ item = mpack_node_map_cstr(reply_node, "dval");
+ reply = swarmkv_reply_new_double(mpack_node_double(item));
+ break;
+ case SWARMKV_REPLY_STRING:
+ case SWARMKV_REPLY_ERROR:
+ case SWARMKV_REPLY_STATUS:
+ case SWARMKV_REPLY_NODE:
+ item = mpack_node_map_cstr(reply_node, "str");
+ reply = swarmkv_reply_new_string(mpack_node_str(item), mpack_node_strlen(item));
+ reply->type = type; // dirty here
+ break;
+ case SWARMKV_REPLY_VERBATIM:
+ item = mpack_node_map_cstr(reply_node, "str");
+ vtype_item = mpack_node_map_cstr(reply_node, "vtype");
+ reply = swarmkv_reply_new_verbatim(mpack_node_str(item), mpack_node_strlen(item), mpack_node_str(vtype_item));
+ break;
+ case SWARMKV_REPLY_NIL:
+ reply = swarmkv_reply_new_nil();
+ break;
+ case SWARMKV_REPLY_ARRAY:
+ array_node = mpack_node_map_cstr(reply_node, "arr");
+ reply = swarmkv_reply_new_array(mpack_node_array_length(array_node));
+ for (i = 0; i < reply->n_element; i++)
+ {
+ item = mpack_node_array_at(array_node, i);
+ reply->elements[i] = deserialize_reply(item);
+ }
+ break;
+ default:
+ assert(0);
+ break;
}
return reply;
}
@@ -57,17 +56,18 @@ static struct swarmkv_reply *swarmkv_reply_deserialize(const char *blob, size_t
mpack_tree_t tree;
mpack_tree_init_data(&tree, blob, size);
mpack_tree_parse(&tree);
-
- mpack_node_t root=mpack_tree_root(&tree);
- struct swarmkv_reply *reply=NULL;
- reply=deserialize_reply(root);
- if (mpack_tree_destroy(&tree) != mpack_ok) {
+ mpack_node_t root = mpack_tree_root(&tree);
+ struct swarmkv_reply *reply = NULL;
+ reply = deserialize_reply(root);
+
+ if (mpack_tree_destroy(&tree) != mpack_ok)
+ {
fprintf(stderr, "An error occurred decoding a reply blob!\n");
assert(0);
swarmkv_reply_free(reply);
return NULL;
- }
+ }
return reply;
}
static struct swarmkv_cmd *swarmkv_cmd_deserialize(const char *blob, size_t size)
@@ -75,27 +75,28 @@ static struct swarmkv_cmd *swarmkv_cmd_deserialize(const char *blob, size_t size
mpack_tree_t tree;
mpack_tree_init_data(&tree, blob, size);
mpack_tree_parse(&tree);
-
+
mpack_node_t item, array_node;
- mpack_node_t root=mpack_tree_root(&tree);
- struct swarmkv_cmd *cmd=NULL;
- const char *arg=NULL;
- size_t sz=0;
+ mpack_node_t root = mpack_tree_root(&tree);
+ struct swarmkv_cmd *cmd = NULL;
+ const char *arg = NULL;
+ size_t sz = 0;
node_t caller;
- item=mpack_node_map_cstr(root, "caller");
+ item = mpack_node_map_cstr(root, "caller");
node_init_from_string(&caller, mpack_node_str(item), mpack_node_strlen(item));
assert(node_sanity(&caller));
- //assert(sz==sizeof(node_t));
- array_node=mpack_node_map_cstr(root, "argv");
- cmd=swarmkv_cmd_new(mpack_node_array_length(array_node), &caller);
- for(size_t i=0; i<cmd->argc; i++)
+ // assert(sz==sizeof(node_t));
+ array_node = mpack_node_map_cstr(root, "argv");
+ cmd = swarmkv_cmd_new(mpack_node_array_length(array_node), &caller);
+ for (size_t i = 0; i < cmd->argc; i++)
{
- item=mpack_node_array_at(array_node, i);
- arg=mpack_node_str(item);
- sz=mpack_node_strlen(item);
- cmd->argv[i]=sdsnewlen(arg, sz);
+ item = mpack_node_array_at(array_node, i);
+ arg = mpack_node_str(item);
+ sz = mpack_node_strlen(item);
+ cmd->argv[i] = sdsnewlen(arg, sz);
}
- if (mpack_tree_destroy(&tree) != mpack_ok) {
+ if (mpack_tree_destroy(&tree) != mpack_ok)
+ {
fprintf(stderr, "An error occurred decoding a cmd blob!\n");
assert(0);
swarmkv_cmd_free(cmd);
@@ -104,198 +105,165 @@ static struct swarmkv_cmd *swarmkv_cmd_deserialize(const char *blob, size_t size
return cmd;
}
-
static void swarmkv_reply_serialize(const struct swarmkv_reply *reply, char **blob, size_t *blob_sz)
{
- char *root_mpack_buff=NULL, *element_mpack_buff=NULL;
- size_t root_mpack_sz=0, element_mpack_size, i=0;
+ char *root_mpack_buff = NULL, *element_mpack_buff = NULL;
+ size_t root_mpack_sz = 0, element_mpack_size, i = 0;
mpack_writer_t writer;
mpack_writer_init_growable(&writer, &root_mpack_buff, &root_mpack_sz);
mpack_build_map(&writer);
mpack_write_cstr(&writer, "t");
mpack_write_int(&writer, reply->type);
- switch(reply->type)
+ switch (reply->type)
{
- case SWARMKV_REPLY_INTEGER:
- mpack_write_cstr(&writer, "int");
- mpack_write_i64(&writer, reply->integer);
- break;
- case SWARMKV_REPLY_DOUBLE:
- mpack_write_cstr(&writer, "dval");
- mpack_write_double(&writer, reply->dval);
- break;
- case SWARMKV_REPLY_STRING:
- case SWARMKV_REPLY_STATUS:
- case SWARMKV_REPLY_ERROR:
- case SWARMKV_REPLY_NODE:
- mpack_write_cstr(&writer, "str");
- mpack_write_str(&writer, reply->str, reply->len);
- break;
- case SWARMKV_REPLY_VERBATIM:
- mpack_write_cstr(&writer, "str");
- mpack_write_str(&writer, reply->str, reply->len);
- mpack_write_cstr(&writer, "vtype");
- mpack_write_cstr(&writer, reply->vtype);
- break;
- case SWARMKV_REPLY_NIL:
- break;
- case SWARMKV_REPLY_ARRAY:
- mpack_write_cstr(&writer, "arr");
- mpack_build_array(&writer);
- for(i=0; i<reply->n_element; i++)
- {
- swarmkv_reply_serialize(reply->elements[i], &element_mpack_buff, &element_mpack_size);
- mpack_write_object_bytes(&writer, element_mpack_buff, element_mpack_size);
- free(element_mpack_buff);
- element_mpack_size=0;
- }
- mpack_complete_array(&writer);
- break;
- default:
- assert(0);
+ case SWARMKV_REPLY_INTEGER:
+ mpack_write_cstr(&writer, "int");
+ mpack_write_i64(&writer, reply->integer);
+ break;
+ case SWARMKV_REPLY_DOUBLE:
+ mpack_write_cstr(&writer, "dval");
+ mpack_write_double(&writer, reply->dval);
+ break;
+ case SWARMKV_REPLY_STRING:
+ case SWARMKV_REPLY_STATUS:
+ case SWARMKV_REPLY_ERROR:
+ case SWARMKV_REPLY_NODE:
+ mpack_write_cstr(&writer, "str");
+ mpack_write_str(&writer, reply->str, reply->len);
+ break;
+ case SWARMKV_REPLY_VERBATIM:
+ mpack_write_cstr(&writer, "str");
+ mpack_write_str(&writer, reply->str, reply->len);
+ mpack_write_cstr(&writer, "vtype");
+ mpack_write_cstr(&writer, reply->vtype);
+ break;
+ case SWARMKV_REPLY_NIL:
+ break;
+ case SWARMKV_REPLY_ARRAY:
+ mpack_write_cstr(&writer, "arr");
+ mpack_build_array(&writer);
+ for (i = 0; i < reply->n_element; i++)
+ {
+ swarmkv_reply_serialize(reply->elements[i], &element_mpack_buff, &element_mpack_size);
+ mpack_write_object_bytes(&writer, element_mpack_buff, element_mpack_size);
+ free(element_mpack_buff);
+ element_mpack_size = 0;
+ }
+ mpack_complete_array(&writer);
+ break;
+ default:
+ assert(0);
}
mpack_complete_map(&writer);
- if (mpack_writer_destroy(&writer) != mpack_ok) {
+ if (mpack_writer_destroy(&writer) != mpack_ok)
+ {
fprintf(stderr, "An error occurred encoding the reply!\n");
return;
}
- *blob=root_mpack_buff;
- *blob_sz=root_mpack_sz;
+ *blob = root_mpack_buff;
+ *blob_sz = root_mpack_sz;
return;
}
static void swarmkv_cmd_serialize(const struct swarmkv_cmd *cmd, char **blob, size_t *blob_sz)
{
- char *root_mpack_buff=NULL;
- size_t root_mpack_sz=0;
+ char *root_mpack_buff = NULL;
+ size_t root_mpack_sz = 0;
mpack_writer_t writer;
- size_t i=0;
+ size_t i = 0;
mpack_writer_init_growable(&writer, &root_mpack_buff, &root_mpack_sz);
mpack_build_map(&writer);
mpack_write_cstr(&writer, "caller");
mpack_write_cstr(&writer, node_addr2cstr(&cmd->caller));
mpack_write_cstr(&writer, "argv");
mpack_build_array(&writer);
- for(i=0; i<cmd->argc; i++)
+ for (i = 0; i < cmd->argc; i++)
{
mpack_write_str(&writer, cmd->argv[i], (uint32_t)sdslen(cmd->argv[i]));
}
mpack_complete_array(&writer);
mpack_complete_map(&writer);
- if (mpack_writer_destroy(&writer) != mpack_ok) {
+ if (mpack_writer_destroy(&writer) != mpack_ok)
+ {
fprintf(stderr, "An error occurred encoding the cmd!\n");
return;
}
- *blob=root_mpack_buff;
- *blob_sz=root_mpack_sz;
+ *blob = root_mpack_buff;
+ *blob_sz = root_mpack_sz;
return;
}
-struct swarmkv_msg *swarmkv_msg_new_by_cmd(const struct swarmkv_cmd *cmd, const node_t *caller, int caller_tid, const node_t *executor, long long sequence)
+struct swarmkv_msg *swarmkv_msg_new_by_cmd(const struct swarmkv_cmd *cmd, long long sequence)
{
- struct swarmkv_msg *msg=ALLOC(struct swarmkv_msg, 1);
- msg->magic=SWARMKV_MSG_MAGIC;
- msg->type=MSG_TYPE_CMD;
- msg->caller_tid=caller_tid;
- msg->sequence=sequence;
- node_copy(&msg->caller, caller);
- if(executor) node_copy(&msg->executor, executor);
- msg->cmd=swarmkv_cmd_dup(cmd);
+ struct swarmkv_msg *msg = ALLOC(struct swarmkv_msg, 1);
+ msg->type = SWARMKV_MSG_TYPE_CMD;
+ msg->sequence = sequence;
+ msg->cmd = swarmkv_cmd_dup(cmd);
return msg;
}
-struct swarmkv_msg *swarmkv_msg_new_by_reply(const struct swarmkv_reply *reply, const node_t *caller, int caller_tid, const node_t *executor, long long sequence)
+struct swarmkv_msg *swarmkv_msg_new_by_reply(const struct swarmkv_reply *reply, long long sequence)
{
- struct swarmkv_msg *msg=ALLOC(struct swarmkv_msg, 1);
- msg->magic=SWARMKV_MSG_MAGIC;
- msg->type=MSG_TYPE_REPLY;
- msg->caller_tid=caller_tid;
- msg->sequence=sequence;
- node_copy(&msg->caller, caller);
- node_copy(&msg->executor, executor);
- msg->reply=swarmkv_reply_dup(reply);
+ struct swarmkv_msg *msg = ALLOC(struct swarmkv_msg, 1);
+ msg->type = SWARMKV_MSG_TYPE_REPLY;
+ msg->sequence = sequence;
+ msg->reply = swarmkv_reply_dup(reply);
return msg;
}
void swarmkv_msg_free(struct swarmkv_msg *msg)
{
- if(msg->type==MSG_TYPE_CMD)
+ if (msg->type == SWARMKV_MSG_TYPE_CMD)
{
swarmkv_cmd_free(msg->cmd);
- msg->cmd=NULL;
+ msg->cmd = NULL;
}
else
{
swarmkv_reply_free(msg->reply);
- msg->reply=NULL;
+ msg->reply = NULL;
}
free(msg);
return;
}
-#define COMPRESS_ENABLED
+#define SWARMKV_MSG_HDR_SIZE offsetof(struct swarmkv_msg, cmd)
void swarmkv_msg_serialize(const struct swarmkv_msg *msg, char **blob, size_t *blob_sz)
{
- char *payload=NULL;
- size_t payload_len=0;
- if(msg->type==MSG_TYPE_CMD)
+ char *payload = NULL;
+ size_t payload_len = 0;
+ if (msg->type == SWARMKV_MSG_TYPE_CMD)
{
- assert(msg->cmd->argc>0);
+ assert(msg->cmd->argc > 0);
swarmkv_cmd_serialize(msg->cmd, &payload, &payload_len);
}
else
{
- assert(msg->reply!=NULL);
+ assert(msg->reply != NULL);
swarmkv_reply_serialize(msg->reply, &payload, &payload_len);
}
- size_t compressed_length = snappy_max_compressed_length(payload_len);
- *blob=ALLOC(char, compressed_length+SWARMKV_MSG_HDR_SIZE);
- if(SNAPPY_OK != snappy_compress(payload, payload_len, *blob+SWARMKV_MSG_HDR_SIZE, &compressed_length))
- {
- fprintf(stderr, "snappy_compress failed\n");
- assert(0);
- }
+ *blob = ALLOC(char, SWARMKV_MSG_HDR_SIZE + payload_len);
memcpy(*blob, msg, SWARMKV_MSG_HDR_SIZE);
- struct swarmkv_msg *pseudo_hdr=NULL;
- pseudo_hdr=(struct swarmkv_msg *)*blob;
- pseudo_hdr->payload_len=compressed_length;
- *blob_sz=compressed_length+SWARMKV_MSG_HDR_SIZE;
+ memcpy(*blob + SWARMKV_MSG_HDR_SIZE, payload, payload_len);
free(payload);
+ *blob_sz = SWARMKV_MSG_HDR_SIZE + payload_len;
return;
}
struct swarmkv_msg *swarmkv_msg_deserialize(const char *blob, size_t size)
{
- struct swarmkv_msg *tmp=(struct swarmkv_msg *)blob;
- if(tmp->magic!=SWARMKV_MSG_MAGIC)
- {
- return NULL;
- }
- if(tmp->payload_len+SWARMKV_MSG_HDR_SIZE!=size)
- {
- return NULL;
- }
- struct swarmkv_msg *msg=ALLOC(struct swarmkv_msg, 1);
+ const char *payload = blob + SWARMKV_MSG_HDR_SIZE;
+ size_t payload_len = size - SWARMKV_MSG_HDR_SIZE;
+
+ struct swarmkv_msg *msg = ALLOC(struct swarmkv_msg, 1);
memcpy(msg, blob, SWARMKV_MSG_HDR_SIZE);
- size_t uncompressed_length=0;
- if (SNAPPY_OK != snappy_uncompressed_length(blob+SWARMKV_MSG_HDR_SIZE, msg->payload_len, &uncompressed_length))
- {
- fprintf(stderr, "snappy_uncompressed_length failed\n");
- assert(0);
- }
- char *uncompressed_data=ALLOC(char, uncompressed_length);
- if(SNAPPY_OK != snappy_uncompress(blob+SWARMKV_MSG_HDR_SIZE, msg->payload_len, uncompressed_data, &uncompressed_length))
- {
- fprintf(stderr, "snappy_uncompress failed\n");
- assert(0);
- }
- if(msg->type==MSG_TYPE_CMD)
+
+ if (msg->type == SWARMKV_MSG_TYPE_CMD)
{
- msg->cmd=swarmkv_cmd_deserialize(uncompressed_data, uncompressed_length);
+ msg->cmd = swarmkv_cmd_deserialize(payload, payload_len);
}
else
{
- msg->reply=swarmkv_reply_deserialize(uncompressed_data, uncompressed_length);
+ msg->reply = swarmkv_reply_deserialize(payload, payload_len);
}
- free(uncompressed_data);
return msg;
} \ No newline at end of file
diff --git a/src/swarmkv_message.h b/src/swarmkv_message.h
index b22f421..ebc8801 100644
--- a/src/swarmkv_message.h
+++ b/src/swarmkv_message.h
@@ -2,39 +2,27 @@
#include "swarmkv/swarmkv.h"
#include "swarmkv_common.h"
-enum MSG_TYPE
+#include <stdint.h>
+
+enum swarmkv_msg_type
{
- MSG_TYPE_CMD,
- MSG_TYPE_REPLY
+ SWARMKV_MSG_TYPE_CMD,
+ SWARMKV_MSG_TYPE_REPLY
};
-#define SWARMKV_MSG_MAGIC 0x5211
struct swarmkv_msg
{
- unsigned int magic;
- enum MSG_TYPE type;
- long long sequence;
- long long ts_val; //TS Value in usec
- long long ts_ecr; //TS Echo Reply in usec
- int caller_tid;
- unsigned int payload_len;
- node_t caller;
- node_t executor;
+ enum swarmkv_msg_type type;
+ uint64_t sequence;
union
{
struct swarmkv_cmd *cmd;
struct swarmkv_reply *reply;
- void *payload;
};
};
-#define SWARMKV_MSG_HDR_SIZE offsetof(struct swarmkv_msg, payload)
-struct swarmkv_msg *swarmkv_msg_new_by_cmd(const struct swarmkv_cmd *cmd, const node_t *caller, int caller_tid, const node_t *executor, long long sequence);
-struct swarmkv_msg *swarmkv_msg_new_by_reply(const struct swarmkv_reply *reply, const node_t *caller, int caller_tid, const node_t *executor, long long sequence);
+struct swarmkv_msg *swarmkv_msg_new_by_cmd(const struct swarmkv_cmd *cmd, long long sequence);
+struct swarmkv_msg *swarmkv_msg_new_by_reply(const struct swarmkv_reply *reply, long long sequence);
void swarmkv_msg_free(struct swarmkv_msg *msg);
-//on_msg_callback_t transfers ownership of msg to the callback function
-typedef void on_msg_callback_t(struct swarmkv_msg *msg, void *arg);
-
-
void swarmkv_msg_serialize(const struct swarmkv_msg *msg, char **blob, size_t *blob_sz);
struct swarmkv_msg *swarmkv_msg_deserialize(const char *blob, size_t size); \ No newline at end of file
diff --git a/src/swarmkv_monitor.c b/src/swarmkv_monitor.c
index 67d8f19..e5caad6 100644
--- a/src/swarmkv_monitor.c
+++ b/src/swarmkv_monitor.c
@@ -11,9 +11,9 @@
#include <hdr/hdr_interval_recorder.h>
#include <pthread.h>
-#define KEY_LEN_MAX 64
+#define KEY_LEN_MAX 64
#define SIGNIFICANT_FIGURES 2
-#define LOWEST_TRACKABLE_VALUE 1
+#define LOWEST_TRACKABLE_VALUE 1
struct recorder
{
char key[KEY_LEN_MAX];
@@ -25,11 +25,11 @@ struct recorder
};
struct recorder *recorder_new(const char *key, long long max_latency_usec)
{
- struct recorder *recorder=ALLOC(struct recorder, 1);
+ struct recorder *recorder = ALLOC(struct recorder, 1);
strncpy(recorder->key, key, sizeof(recorder->key));
- int __attribute__((__unused__))ret=0;
- ret=hdr_interval_recorder_init_all(&recorder->hdr_interval, LOWEST_TRACKABLE_VALUE, max_latency_usec, SIGNIFICANT_FIGURES);
- assert(ret==0);
+ int __attribute__((__unused__)) ret = 0;
+ ret = hdr_interval_recorder_init_all(&recorder->hdr_interval, LOWEST_TRACKABLE_VALUE, max_latency_usec, SIGNIFICANT_FIGURES);
+ assert(ret == 0);
hdr_init(1, max_latency_usec, 2, &recorder->hdr_all_time);
clock_gettime(CLOCK_MONOTONIC, &(recorder->last_sampled));
return recorder;
@@ -38,9 +38,9 @@ void recorder_free(struct recorder *recorder)
{
hdr_interval_recorder_destroy(&recorder->hdr_interval);
hdr_close(recorder->hdr_all_time);
- recorder->hdr_all_time=NULL;
+ recorder->hdr_all_time = NULL;
hdr_close(recorder->hdr_previous);
- recorder->hdr_previous=NULL;
+ recorder->hdr_previous = NULL;
free(recorder);
return;
}
@@ -53,54 +53,30 @@ struct recorder_metric
double stddev, mean;
long long p50, p80, p90, p95, p99;
};
-size_t metric2string(const struct recorder_metric *metric, char *buff, size_t buff_sz)
-{
- return snprintf(buff, buff_sz, "p50_usec=%lld "
- "p80_usec=%lld "
- "p90_usec=%lld "
- "p95_usec=%lld "
- "p99_usec=%lld "
- "max_usec=%lld "
- "min_usec=%lld "
- "mean_usec=%.2f "
- "stddev=%.2f "
- "count=%lld"
- ,
- metric->p50,
- metric->p80,
- metric->p90,
- metric->p95,
- metric->p99,
- metric->max,
- metric->min,
- metric->mean,
- metric->stddev,
- metric->total_count
- );
-}
void hdr_to_metric(const struct hdr_histogram *hdr, const char *key, struct recorder_metric *metric)
{
memset(metric, 0, sizeof(struct recorder_metric));
strncpy(metric->key, key, sizeof(metric->key));
- metric->total_count=hdr->total_count;
- if(metric->total_count==0) return;
- metric->p50=hdr_value_at_percentile(hdr, 50);
- metric->p80=hdr_value_at_percentile(hdr, 80);
- metric->p90=hdr_value_at_percentile(hdr, 90);
- metric->p95=hdr_value_at_percentile(hdr, 95);
- metric->p99=hdr_value_at_percentile(hdr, 99);
- metric->total_count=hdr->total_count;
- metric->max=hdr_max(hdr);
- metric->mean=hdr_mean(hdr);
- metric->min=hdr_min(hdr);
- metric->stddev=hdr_stddev(hdr);
+ metric->total_count = hdr->total_count;
+ if (metric->total_count == 0)
+ return;
+ metric->p50 = hdr_value_at_percentile(hdr, 50);
+ metric->p80 = hdr_value_at_percentile(hdr, 80);
+ metric->p90 = hdr_value_at_percentile(hdr, 90);
+ metric->p95 = hdr_value_at_percentile(hdr, 95);
+ metric->p99 = hdr_value_at_percentile(hdr, 99);
+ metric->total_count = hdr->total_count;
+ metric->max = hdr_max(hdr);
+ metric->mean = hdr_mean(hdr);
+ metric->min = hdr_min(hdr);
+ metric->stddev = hdr_stddev(hdr);
return;
}
void recorder_commit(struct recorder *recorder)
{
- recorder->hdr_previous=hdr_interval_recorder_sample_and_recycle(&recorder->hdr_interval, recorder->hdr_previous);
- long long __attribute__((__unused__))dropped=hdr_add(recorder->hdr_all_time, recorder->hdr_previous);
- assert(dropped==0);
+ recorder->hdr_previous = hdr_interval_recorder_sample_and_recycle(&recorder->hdr_interval, recorder->hdr_previous);
+ long long __attribute__((__unused__)) dropped = hdr_add(recorder->hdr_all_time, recorder->hdr_previous);
+ assert(dropped == 0);
return;
}
void recorder_sample(struct recorder *recorder, struct recorder_metric *metric)
@@ -112,7 +88,7 @@ void recorder_sample(struct recorder *recorder, struct recorder_metric *metric)
void recorder_reset(struct recorder *recorder)
{
- recorder->hdr_previous=hdr_interval_recorder_sample_and_recycle(&recorder->hdr_interval, recorder->hdr_previous);
+ recorder->hdr_previous = hdr_interval_recorder_sample_and_recycle(&recorder->hdr_interval, recorder->hdr_previous);
hdr_reset(recorder->hdr_previous);
hdr_reset(recorder->hdr_all_time);
return;
@@ -123,14 +99,14 @@ void recorder_record(struct recorder *recorder, long long latency_usec, long lon
}
void recorder_table_record_latency(struct recorder **table, const char *key, size_t key_len, long long latency_usec, long long corrected, int add_if_not_exist)
{
- struct recorder *recorder=NULL;
+ struct recorder *recorder = NULL;
HASH_FIND(hh, *table, key, key_len, recorder);
- if(!recorder)
+ if (!recorder)
{
- if(add_if_not_exist)
+ if (add_if_not_exist)
{
- recorder=recorder_new(key, corrected);
- HASH_ADD_KEYPTR(hh, *table, recorder->key, strlen(recorder->key), recorder);
+ recorder = recorder_new(key, corrected);
+ HASH_ADD_KEYPTR(hh, *table, recorder->key, strlen(recorder->key), recorder);
}
else
{
@@ -143,28 +119,28 @@ void recorder_table_record_latency(struct recorder **table, const char *key, siz
}
void recorder_table_reset(struct recorder **table)
{
- struct recorder *recorder=NULL, *tmp=NULL;
+ struct recorder *recorder = NULL, *tmp = NULL;
HASH_ITER(hh, *table, recorder, tmp)
{
- recorder_reset(recorder);
+ recorder_reset(recorder);
}
return;
}
-void recorder_table_merge(struct recorder **src_tables, size_t n_table, struct recorder **dst_table)
+void recorder_table_merge(struct recorder **src_tables, size_t n_table, struct recorder **dst_table)
{
- struct recorder *dst_recorder=NULL;
- struct recorder *src_recorder=NULL, *tmp=NULL;
- for(size_t i=0; i<n_table; i++)
+ struct recorder *dst_recorder = NULL;
+ struct recorder *src_recorder = NULL, *tmp = NULL;
+ for (size_t i = 0; i < n_table; i++)
{
- src_recorder=NULL;
- tmp=NULL;
+ src_recorder = NULL;
+ tmp = NULL;
HASH_ITER(hh, src_tables[i], src_recorder, tmp)
{
-
+
HASH_FIND(hh, *dst_table, src_recorder->key, strlen(src_recorder->key), dst_recorder);
- if(!dst_recorder)
+ if (!dst_recorder)
{
- dst_recorder=recorder_new(src_recorder->key, src_recorder->hdr_all_time->highest_trackable_value);
+ dst_recorder = recorder_new(src_recorder->key, src_recorder->hdr_all_time->highest_trackable_value);
HASH_ADD_KEYPTR(hh, *dst_table, dst_recorder->key, strlen(dst_recorder->key), dst_recorder);
}
recorder_commit(src_recorder);
@@ -179,48 +155,40 @@ size_t recorder_table_count(struct recorder **table)
}
int recorder_table_sample_key(struct recorder **table, const char *key, struct recorder_metric *metric)
{
- struct recorder *recorder=NULL, *tmp=NULL;
- HASH_ITER(hh, *table, recorder, tmp)
- {
- if(0==strncasecmp(recorder->key, key, strlen(key)))
- {
- recorder_sample(recorder, metric);
- return 1;
- }
- }
+ struct recorder *recorder = NULL, *tmp = NULL;
+ HASH_ITER(hh, *table, recorder, tmp)
+ {
+ if (0 == strncasecmp(recorder->key, key, strlen(key)))
+ {
+ recorder_sample(recorder, metric);
+ return 1;
+ }
+ }
return 0;
}
void recorder_table_sample_all(struct recorder **table, struct recorder_metric **metrics, size_t *n_metric)
{
- struct recorder *recorder=NULL, *tmp=NULL;
- *n_metric=HASH_COUNT(*table);
- *metrics=ALLOC(struct recorder_metric, *n_metric);
- size_t i=0;
+ struct recorder *recorder = NULL, *tmp = NULL;
+ *n_metric = HASH_COUNT(*table);
+ *metrics = ALLOC(struct recorder_metric, *n_metric);
+ size_t i = 0;
HASH_ITER(hh, *table, recorder, tmp)
{
- recorder_sample(recorder, *metrics+i);
+ recorder_sample(recorder, *metrics + i);
i++;
}
return;
}
void recorder_table_free(struct recorder **table)
{
- struct recorder *recorder=NULL, *tmp=NULL;
- HASH_ITER(hh, *table, recorder, tmp)
- {
+ struct recorder *recorder = NULL, *tmp = NULL;
+ HASH_ITER(hh, *table, recorder, tmp)
+ {
HASH_DEL(*table, recorder);
recorder_free(recorder);
- }
-}
-struct swarmkv_reply *recorder_metric_to_reply(const struct recorder_metric *metric)
-{
- char metric_buff[1024];
- metric2string(metric, metric_buff, sizeof(metric_buff));
- struct swarmkv_reply *reply=swarmkv_reply_new_array(2);
- reply->elements[0]=swarmkv_reply_new_string_fmt(metric->key);
- reply->elements[1]=swarmkv_reply_new_string_fmt(metric_buff);
- return reply;
+ }
}
+
struct monitor_client
{
node_t node;
@@ -229,9 +197,9 @@ struct monitor_client
};
struct monitor_client *monitor_client_new(const node_t *node, sds pattern)
{
- struct monitor_client *client=ALLOC(struct monitor_client, 1);
+ struct monitor_client *client = ALLOC(struct monitor_client, 1);
node_copy(&client->node, node);
- client->pattern = pattern? sdsdup(pattern):NULL;
+ client->pattern = pattern ? sdsdup(pattern) : NULL;
return client;
}
void monitor_client_free(struct monitor_client *client)
@@ -254,62 +222,62 @@ struct swarmkv_monitor
struct recorder **peers;
long long max_latency_usec;
int significant_figures;
- int nr_worker_threads;
+ int nr_threads;
struct swarmkv_monitor_thread *threads;
- pthread_mutex_t latency_execute_mutex; //only one latency command can be executed at a time
+ pthread_mutex_t latency_execute_mutex; // only one latency command can be executed at a time
struct swarmkv *ref_db;
};
struct swarmkv_monitor *module2monitor(struct swarmkv_module *module)
{
- assert(0==strcmp(module->name, "monitor"));
- struct swarmkv_monitor *monitor=container_of(module, struct swarmkv_monitor, module);
- assert(monitor==module->mod_ctx);
- return monitor;
+ assert(0 == strcmp(module->name, "monitor"));
+ struct swarmkv_monitor *monitor = container_of(module, struct swarmkv_monitor, module);
+ assert(monitor == module->mod_ctx);
+ return monitor;
}
struct swarmkv_module *swarmkv_monitor_new(const struct swarmkv_options *opts, struct swarmkv *db)
{
- struct swarmkv_monitor *monitor=ALLOC(struct swarmkv_monitor, 1);
- monitor->max_latency_usec=opts->cluster_timeout_us;
- monitor->nr_worker_threads=opts->nr_worker_threads;
- monitor->peers=ALLOC(struct recorder *, monitor->nr_worker_threads);
+ struct swarmkv_monitor *monitor = ALLOC(struct swarmkv_monitor, 1);
+ monitor->max_latency_usec = opts->cluster_timeout_us;
+ monitor->nr_threads = opts->total_threads;
+ monitor->peers = ALLOC(struct recorder *, monitor->nr_threads);
strncpy(monitor->module.name, "monitor", sizeof(monitor->module.name));
- monitor->module.mod_ctx=monitor;
+ monitor->module.mod_ctx = monitor;
pthread_mutex_init(&monitor->latency_execute_mutex, NULL);
- monitor->threads=ALLOC(struct swarmkv_monitor_thread, monitor->nr_worker_threads);
- for(size_t i=0; i<monitor->nr_worker_threads; i++)
+ monitor->threads = ALLOC(struct swarmkv_monitor_thread, monitor->nr_threads);
+ for (size_t i = 0; i < monitor->nr_threads; i++)
{
pthread_mutex_init(&monitor->threads[i].mutex, PTHREAD_PROCESS_PRIVATE);
- monitor->threads[i].clients=NULL;
+ monitor->threads[i].clients = NULL;
}
- monitor->ref_db=db;
+ monitor->ref_db = db;
return &monitor->module;
}
void swarmkv_monitor_register_command(struct swarmkv_module *mod_monitor, const char *command)
{
- struct swarmkv_monitor *monitor=module2monitor(mod_monitor);
- struct recorder *recorder=NULL;
- recorder=recorder_new(command, monitor->max_latency_usec);
+ struct swarmkv_monitor *monitor = module2monitor(mod_monitor);
+ struct recorder *recorder = NULL;
+ recorder = recorder_new(command, monitor->max_latency_usec);
HASH_ADD_KEYPTR(hh, monitor->commands, recorder->key, strlen(recorder->key), recorder);
return;
}
void swarmkv_monitor_register_event(struct swarmkv_module *mod_monitor, const char *event)
{
- struct swarmkv_monitor *monitor=module2monitor(mod_monitor);
- struct recorder *recorder=NULL;
- recorder=recorder_new(event, monitor->max_latency_usec);
+ struct swarmkv_monitor *monitor = module2monitor(mod_monitor);
+ struct recorder *recorder = NULL;
+ recorder = recorder_new(event, monitor->max_latency_usec);
HASH_ADD_KEYPTR(hh, monitor->events, recorder->key, strlen(recorder->key), recorder);
return;
}
void swarmkv_monitor_free(struct swarmkv_module *mod_monitor)
{
- struct swarmkv_monitor *monitor=module2monitor(mod_monitor);
+ struct swarmkv_monitor *monitor = module2monitor(mod_monitor);
recorder_table_free(&monitor->commands);
recorder_table_free(&monitor->events);
- for(size_t i=0; i<monitor->nr_worker_threads; i++)
+ for (size_t i = 0; i < monitor->nr_threads; i++)
{
- recorder_table_free(monitor->peers+i);
- struct monitor_client *client=NULL, *tmp=NULL;
+ recorder_table_free(monitor->peers + i);
+ struct monitor_client *client = NULL, *tmp = NULL;
LL_FOREACH_SAFE(monitor->threads[i].clients, client, tmp)
{
LL_DELETE(monitor->threads[i].clients, client);
@@ -318,7 +286,7 @@ void swarmkv_monitor_free(struct swarmkv_module *mod_monitor)
}
free(monitor->threads);
free(monitor->peers);
- monitor->peers=NULL;
+ monitor->peers = NULL;
free(monitor);
}
struct print_ctx
@@ -329,15 +297,15 @@ struct print_ctx
};
static void print_on_reply(const struct swarmkv_reply *reply, void *user)
{
- struct print_ctx *ctx=(struct print_ctx *)user;
-
- if(reply->type != SWARMKV_REPLY_STATUS)
+ struct print_ctx *ctx = (struct print_ctx *)user;
+
+ if (reply->type != SWARMKV_REPLY_STATUS)
{
- struct monitor_client *client=NULL, *tmp=NULL;
+ struct monitor_client *client = NULL, *tmp = NULL;
pthread_mutex_lock(&ctx->monitor->threads[ctx->tid].mutex);
LL_FOREACH_SAFE(ctx->monitor->threads[ctx->tid].clients, client, tmp)
{
- if(0==node_compare(&client->node, &ctx->node))
+ if (0 == node_compare(&client->node, &ctx->node))
{
ctx->monitor->threads[ctx->tid].n_client--;
LL_DELETE(ctx->monitor->threads[ctx->tid].clients, client);
@@ -348,269 +316,294 @@ static void print_on_reply(const struct swarmkv_reply *reply, void *user)
}
else
{
- int tid=swarmkv_gettid(ctx->monitor->ref_db);
- assert(tid==ctx->tid);
+ int tid = swarmkv_gettid(ctx->monitor->ref_db);
+ assert(tid == ctx->tid);
}
free(ctx);
}
static const char *exec_ret2string(enum cmd_exec_result ret)
{
- switch(ret)
- {
- case NEED_KEY_ROUTE:
- return "KRT";
- case REDIRECT:
- return "RDR";
- case FINISHED:
- return "FIN";
- default:
- assert(0);
- }
+ switch (ret)
+ {
+ case NEED_KEY_ROUTE:
+ return "KRT";
+ case REDIRECT:
+ return "RDR";
+ case FINISHED:
+ return "FIN";
+ default:
+ assert(0);
+ }
}
void swarmkv_monitor_record_command(struct swarmkv_module *mod_monitor, const struct swarmkv_cmd_spec *spec, const struct swarmkv_cmd *cmd, long long latency_usec, enum cmd_exec_result result)
{
- struct swarmkv_monitor *monitor=module2monitor(mod_monitor);
+ struct swarmkv_monitor *monitor = module2monitor(mod_monitor);
recorder_table_record_latency(&monitor->commands, spec->name, strlen(spec->name), latency_usec, monitor->max_latency_usec, 0);
- int tid=swarmkv_gettid(monitor->ref_db);
- assert(tid<monitor->nr_worker_threads);
- if(0==strncasecmp(spec->name, "PRINT", strlen("PRINT")))
+ int tid = swarmkv_gettid(monitor->ref_db);
+ assert(tid < monitor->nr_threads);
+ if (0 == strncasecmp(spec->name, "PRINT", strlen("PRINT")))
{
- //Do not log print command to avoid infinit recursion.
+ // Do not log print command to avoid infinit recursion.
return;
}
- if(monitor->threads[tid].n_client == 0)
+ if (monitor->threads[tid].n_client == 0)
{
- //No monitor client registered.
+ // No monitor client registered.
return;
}
- struct monitor_client *client=NULL;
- int matched_client=0;
+ struct monitor_client *client = NULL;
+ int matched_client = 0;
node_t matched_client_nodes[monitor->threads[tid].n_client];
pthread_mutex_lock(&monitor->threads[tid].mutex);
LL_FOREACH(monitor->threads[tid].clients, client)
{
- if(client->pattern)
+ if (client->pattern)
{
- int is_matched=0;
- for(int i=0; i<cmd->argc; i++)
+ int is_matched = 0;
+ for (int i = 0; i < cmd->argc; i++)
{
- is_matched=stringmatchlen(client->pattern, sdslen(client->pattern), cmd->argv[i], sdslen(cmd->argv[i]), 0);
- if(is_matched)
+ is_matched = stringmatchlen(client->pattern, sdslen(client->pattern), cmd->argv[i], sdslen(cmd->argv[i]), 0);
+ if (is_matched)
{
break;
}
}
- if(!is_matched)
+ if (!is_matched)
{
continue;
}
}
- node_copy(matched_client_nodes+matched_client, &client->node);
+ node_copy(matched_client_nodes + matched_client, &client->node);
matched_client++;
}
- //To avoid dead lock, we should not hold the lock when executing command.
+ // To avoid dead lock, we should not hold the lock when executing command.
pthread_mutex_unlock(&monitor->threads[tid].mutex);
assert(matched_client <= monitor->threads[tid].n_client);
- if(matched_client==0)
+ if (matched_client == 0)
{
return;
}
-
+
sds cmdrepr = sdsempty();
struct timeval tv;
gettimeofday(&tv, NULL);
- cmdrepr = sdscatprintf(cmdrepr,"%ld.%06ld ",(long)tv.tv_sec, (long)tv.tv_usec);
- cmdrepr = sdscatprintf(cmdrepr,"[%d %c %s %s] ", tid,
- 0==node_compare(&cmd->caller, swarmkv_self_node(monitor->ref_db))?'L':'R',
- node_addr2cstr(&cmd->caller),
- exec_ret2string(result));
- for(int i=0; i<cmd->argc; i++)
+ cmdrepr = sdscatprintf(cmdrepr, "%ld.%06ld ", (long)tv.tv_sec, (long)tv.tv_usec);
+ cmdrepr = sdscatprintf(cmdrepr, "[%d %c %s %s] ", tid,
+ 0 == node_compare(&cmd->caller, swarmkv_self_node(monitor->ref_db)) ? 'L' : 'R',
+ node_addr2cstr(&cmd->caller),
+ exec_ret2string(result));
+ for (int i = 0; i < cmd->argc; i++)
{
- cmdrepr = sdscatrepr(cmdrepr, (char*)cmd->argv[i], sdslen(cmd->argv[i]));
- if (i != cmd->argc-1)
- cmdrepr = sdscatlen(cmdrepr," ",1);
+ cmdrepr = sdscatrepr(cmdrepr, (char *)cmd->argv[i], sdslen(cmd->argv[i]));
+ if (i != cmd->argc - 1)
+ cmdrepr = sdscatlen(cmdrepr, " ", 1);
}
cmdrepr = sdscatprintf(cmdrepr, "\r\n");
-
+
const char *print_cmd_argv[2];
size_t print_cmd_argv_len[2];
- print_cmd_argv[0]="PRINT";
- print_cmd_argv_len[0]=strlen(print_cmd_argv[0]);
- print_cmd_argv[1]=cmdrepr;
- print_cmd_argv_len[1]=sdslen(cmdrepr);
+ print_cmd_argv[0] = "PRINT";
+ print_cmd_argv_len[0] = strlen(print_cmd_argv[0]);
+ print_cmd_argv[1] = cmdrepr;
+ print_cmd_argv_len[1] = sdslen(cmdrepr);
- for(int i=0; i<matched_client; i++)
+ for (int i = 0; i < matched_client; i++)
{
- struct print_ctx *print_ctx=ALLOC(struct print_ctx, 1);
+ struct print_ctx *print_ctx = ALLOC(struct print_ctx, 1);
node_copy(&print_ctx->node, &matched_client_nodes[i]);
- print_ctx->tid=tid;
- print_ctx->monitor=monitor;
+ print_ctx->tid = tid;
+ print_ctx->monitor = monitor;
swarmkv_async_command_on_argv(monitor->ref_db, print_on_reply, print_ctx, print_ctx->node.addr, 2, print_cmd_argv, print_cmd_argv_len);
}
sdsfree(cmdrepr);
return;
}
-void swarmkv_monitor_record_peer(struct swarmkv_module *mod_monitor, node_t *peer, long long latency_usec, int thread_id)
+void swarmkv_monitor_record_peer(struct swarmkv_module *mod_monitor, const node_t *peer, long long latency_usec, int thread_id)
{
- struct swarmkv_monitor *monitor=module2monitor(mod_monitor);
- assert(thread_id<monitor->nr_worker_threads);
- recorder_table_record_latency(monitor->peers+thread_id, peer->addr, strlen(peer->addr), latency_usec, monitor->max_latency_usec, 1);
+ struct swarmkv_monitor *monitor = module2monitor(mod_monitor);
+ assert(thread_id < monitor->nr_threads);
+ recorder_table_record_latency(monitor->peers + thread_id, peer->addr, strlen(peer->addr), latency_usec, monitor->max_latency_usec, 1);
return;
}
void swarmkv_monitor_record_event(struct swarmkv_module *mod_monitor, const char *event_name, long long latency_usec)
{
- struct swarmkv_monitor *monitor=module2monitor(mod_monitor);
+ struct swarmkv_monitor *monitor = module2monitor(mod_monitor);
recorder_table_record_latency(&monitor->events, event_name, strlen(event_name), latency_usec, monitor->max_latency_usec, 0);
return;
}
+static int get_metric_headers(char *buff, size_t buff_sz)
+{
+ return snprintf(buff, buff_sz, "| %-32s | %-8s | %-8s | %-8s | %-8s | %-8s | %-8s | %-8s | %-8s | %-8s | %-8s |",
+ "Key",
+ "Count",
+ "p50",
+ "p80",
+ "p90",
+ "p95",
+ "p99",
+ "Max",
+ "Min",
+ "Mean",
+ "Stddev");
+}
+size_t metric2string(const struct recorder_metric *metric, char *buff, size_t buff_sz)
+{
+ return snprintf(buff, buff_sz, "| %-32s | %-8lld | %-8lld | %-8lld | %-8lld | %-8lld | %-8lld | %-8lld | %-8lld | %-8.2f | %-8.2f |",
+ metric->key,
+ metric->total_count,
+ metric->p50,
+ metric->p80,
+ metric->p90,
+ metric->p95,
+ metric->p99,
+ metric->max,
+ metric->min,
+ metric->mean,
+ metric->stddev);
+}
struct swarmkv_reply *latency_generic(struct recorder **table, const char *key)
{
- struct swarmkv_reply *reply=NULL;
- struct recorder_metric metric;
- struct recorder_metric *metrics=NULL;
- size_t n_metric=0;
- int ret=0;
- if(key)
+ struct swarmkv_reply *reply = NULL;
+ struct recorder_metric *metrics = NULL;
+ size_t n_metric = 0;
+ int ret = 0;
+ if (key)
{
- ret=recorder_table_sample_key(table, key, &metric);
- if(ret)
- {
- reply=swarmkv_reply_new_array(1);
- reply->elements[0]=recorder_metric_to_reply(&metric);
- }
- else
- {
- reply=swarmkv_reply_new_array(0);
- }
+ metrics = ALLOC(struct recorder_metric, 1);
+ ret = recorder_table_sample_key(table, key, metrics);
+ n_metric = ret ? 1 : 0;
}
else
{
recorder_table_sample_all(table, &metrics, &n_metric);
- reply=swarmkv_reply_new_array(n_metric);
- for(size_t i=0; i<n_metric; i++)
- {
- reply->elements[i]=recorder_metric_to_reply(metrics+i);
- }
- free(metrics);
}
+ reply = swarmkv_reply_new_array(n_metric + 1);
+ char buff[1024];
+ get_metric_headers(buff, sizeof(buff));
+ reply->elements[0] = swarmkv_reply_new_status(buff);
+ for (size_t i = 0; i < n_metric; i++)
+ {
+ metric2string(metrics + i, buff, sizeof(buff));
+ reply->elements[i + 1] = swarmkv_reply_new_status(buff);
+ }
+ free(metrics);
return reply;
}
enum cmd_exec_result latency_command(struct swarmkv_module *mod_monitor, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- struct swarmkv_monitor *monitor=module2monitor(mod_monitor);
+ struct swarmkv_monitor *monitor = module2monitor(mod_monitor);
pthread_mutex_lock(&monitor->latency_execute_mutex);
- if(cmd->argc==2 && !strcasecmp(cmd->argv[1], "help") )
- {
- const char *help = {
-"LATENCY <subcommand> [<arg> [value] [opt] ...]. Subcommands are:\n"
-"COMMAND [command]\n"
-" Return time-latency samples for a specified command name.\n"
-"PEER [IP:port]\n"
-" Return time-latency samples for the specified peer.\n"
-"EVENT [event]\n"
-" Return time-latency samples for the specified event.\n"
-"RESET [command|event|peer]\n"
-" Reset data of a specified catalog or all the data if no catalog provided.\n"
- };
- *reply=swarmkv_reply_new_status(help);
- }
- else if(!strcasecmp(cmd->argv[1], "command"))
+ if (cmd->argc == 2 && !strcasecmp(cmd->argv[1], "help"))
+ {
+ const char *help = {
+ "LATENCY <subcommand> [<arg> [value] [opt] ...]. Subcommands are:\n"
+ "COMMAND [command]\n"
+ " Return time-latency samples for a specified command name.\n"
+ "PEER [IP:port]\n"
+ " Return time-latency samples for the specified peer.\n"
+ "EVENT [event]\n"
+ " Return time-latency samples for the specified event.\n"
+ "RESET [command|event|peer]\n"
+ " Reset data of a specified catalog or all the data if no catalog provided.\n"};
+ *reply = swarmkv_reply_new_status(help);
+ }
+ else if (!strcasecmp(cmd->argv[1], "command"))
{
- *reply=latency_generic(&monitor->commands, cmd->argc>2?cmd->argv[2]:NULL);
+ *reply = latency_generic(&monitor->commands, cmd->argc > 2 ? cmd->argv[2] : NULL);
}
- else if(!strcasecmp(cmd->argv[1], "event"))
+ else if (!strcasecmp(cmd->argv[1], "event"))
{
- *reply=latency_generic(&monitor->events, cmd->argc>2?cmd->argv[2]:NULL);
+ *reply = latency_generic(&monitor->events, cmd->argc > 2 ? cmd->argv[2] : NULL);
}
- else if(!strcasecmp(cmd->argv[1], "peer"))
+ else if (!strcasecmp(cmd->argv[1], "peer"))
{
- struct recorder *merged_table=NULL;
- //Dirty code: Reading all worker threads' peer recorder tables is not thread-safe.
- //It's OK only if the worker threads are not adding new peers.
- recorder_table_merge(monitor->peers, monitor->nr_worker_threads, &merged_table);
- *reply=latency_generic(&merged_table, cmd->argc>2?cmd->argv[2]:NULL);
+ struct recorder *merged_table = NULL;
+ // Dirty code: Reading all worker threads' peer recorder tables is not thread-safe.
+ // It's OK only if the worker threads are not adding new peers.
+ recorder_table_merge(monitor->peers, monitor->nr_threads, &merged_table);
+ *reply = latency_generic(&merged_table, cmd->argc > 2 ? cmd->argv[2] : NULL);
recorder_table_free(&merged_table);
}
- else if(!strcasecmp(cmd->argv[1], "reset"))
+ else if (!strcasecmp(cmd->argv[1], "reset"))
{
- if(cmd->argc>2)
+ if (cmd->argc > 2)
{
- if(!strcasecmp(cmd->argv[2], "command"))
+ if (!strcasecmp(cmd->argv[2], "command"))
{
recorder_table_reset(&monitor->commands);
- *reply=swarmkv_reply_new_status("Command metrics are reset");
+ *reply = swarmkv_reply_new_status("Command metrics are reset");
}
- else if(!strcasecmp(cmd->argv[2], "event"))
+ else if (!strcasecmp(cmd->argv[2], "event"))
{
recorder_table_reset(&monitor->events);
- *reply=swarmkv_reply_new_status("Event metrics are reset");
+ *reply = swarmkv_reply_new_status("Event metrics are reset");
}
- else if(!strcasecmp(cmd->argv[2], "peer"))
+ else if (!strcasecmp(cmd->argv[2], "peer"))
{
- for(size_t i=0; i<monitor->nr_worker_threads; i++)
+ for (size_t i = 0; i < monitor->nr_threads; i++)
{
- recorder_table_reset(monitor->peers+i);
+ recorder_table_reset(monitor->peers + i);
}
- *reply=swarmkv_reply_new_status("Peer metrics are rest");
+ *reply = swarmkv_reply_new_status("Peer metrics are rest");
}
else
{
- *reply=swarmkv_reply_new_error(erorr_subcommand_syntax, cmd->argv[1], cmd->argv[0]);
+ *reply = swarmkv_reply_new_error(erorr_subcommand_syntax, cmd->argv[1], cmd->argv[0]);
}
}
else
{
recorder_table_reset(&monitor->commands);
recorder_table_reset(&monitor->events);
- for(size_t i=0; i<monitor->nr_worker_threads; i++)
+ for (size_t i = 0; i < monitor->nr_threads; i++)
{
- recorder_table_reset(monitor->peers+i);
+ recorder_table_reset(monitor->peers + i);
}
- *reply=swarmkv_reply_new_status("All metrics are reset");
+ *reply = swarmkv_reply_new_status("All metrics are reset");
}
}
else
{
- *reply=swarmkv_reply_new_error(erorr_subcommand_syntax, cmd->argv[1], cmd->argv[0]);
+ *reply = swarmkv_reply_new_error(erorr_subcommand_syntax, cmd->argv[1], cmd->argv[0]);
}
pthread_mutex_unlock(&monitor->latency_execute_mutex);
return FINISHED;
}
enum cmd_exec_result monreg_command(struct swarmkv_module *mod_monitor, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* MONREG IP:port [pattern]*/
- struct swarmkv_monitor *monitor=module2monitor(mod_monitor);
+ /* MONREG IP:port [pattern]*/
+ struct swarmkv_monitor *monitor = module2monitor(mod_monitor);
node_t node;
- int ret=0;
- ret=node_init_from_sds(&node, cmd->argv[1]);
- if(ret<0)
+ int ret = 0;
+ ret = node_init_from_sds(&node, cmd->argv[1]);
+ if (ret < 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_node);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_node);
return FINISHED;
}
- for(int i=0; i<monitor->nr_worker_threads; i++)
+ for (int i = 0; i < monitor->nr_threads; i++)
{
- struct monitor_client *client=NULL;
- int found=0;
+ struct monitor_client *client = NULL;
+ int found = 0;
pthread_mutex_lock(&monitor->threads[i].mutex);
LL_FOREACH(monitor->threads[i].clients, client)
{
- if(0==node_compare(&client->node, &node))
+ if (0 == node_compare(&client->node, &node))
{
sdsfree(client->pattern);
- client->pattern=cmd->argc>2?sdsdup(cmd->argv[2]):NULL;
- found=1;
+ client->pattern = cmd->argc > 2 ? sdsdup(cmd->argv[2]) : NULL;
+ found = 1;
}
}
- if(!found)
+ if (!found)
{
- client=monitor_client_new(&node, cmd->argc>2?cmd->argv[2]:NULL);
+ client = monitor_client_new(&node, cmd->argc > 2 ? cmd->argv[2] : NULL);
LL_APPEND(monitor->threads[i].clients, client);
monitor->threads[i].n_client++;
}
pthread_mutex_unlock(&monitor->threads[i].mutex);
}
- *reply=swarmkv_reply_new_status("OK");
+ *reply = swarmkv_reply_new_status("OK");
return FINISHED;
} \ No newline at end of file
diff --git a/src/swarmkv_monitor.h b/src/swarmkv_monitor.h
index f134618..e2fdd2f 100644
--- a/src/swarmkv_monitor.h
+++ b/src/swarmkv_monitor.h
@@ -11,7 +11,7 @@ void swarmkv_monitor_register_command(struct swarmkv_module *mod_monitor, const
void swarmkv_monitor_free(struct swarmkv_module *mod_monitor);
void swarmkv_monitor_record_command(struct swarmkv_module *mod_monitor, const struct swarmkv_cmd_spec *spec, const struct swarmkv_cmd *cmd, long long latency_usec, enum cmd_exec_result result);
void swarmkv_monitor_register_event(struct swarmkv_module *mod_monitor, const char *event);
-void swarmkv_monitor_record_peer(struct swarmkv_module *mod_monitor, node_t *peer, long long latency_usec, int thread_id);
+void swarmkv_monitor_record_peer(struct swarmkv_module *mod_monitor, const node_t *peer, long long latency_usec, int thread_id);
void swarmkv_monitor_record_event(struct swarmkv_module *mod_monitor, const char *event_name, long long latency_usec);
enum cmd_exec_result latency_command(struct swarmkv_module *mod_monitor, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply);
diff --git a/src/swarmkv_net.c b/src/swarmkv_net.c
index e835ce3..8ac2472 100644
--- a/src/swarmkv_net.c
+++ b/src/swarmkv_net.c
@@ -7,8 +7,9 @@
#include "utarray.h"
#include "xxhash.h"
#include "log.h"
+#include "snappy-c.h"
-//#include <valgrind/memcheck.h> //VALGRIND_CHECK_VALUE_IS_DEFINED
+// #include <valgrind/memcheck.h> //VALGRIND_CHECK_VALUE_IS_DEFINED
#include <event2/listener.h>
#include <event2/bufferevent.h>
@@ -22,33 +23,47 @@
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
-#include <unistd.h> //usleep
-#include <netinet/tcp.h>//setsockopt TCP_NODELAY
+#include <unistd.h> //usleep
+#include <netinet/tcp.h> //setsockopt TCP_NODELAY
+#include <assert.h>
+#define MODULE_SWAMRKV_NET module_name_str("swarmkv.net")
-#define MODULE_SWAMRKV_NET module_name_str("swarmkv.net")
-
+#define SWARMKV_NET_HDR_MAGIC 0x5211
+#define SWARMKV_NET_HDR_VERSION 0x01
+#define COMPRESSION_FLAG_NONE 0
+#define COMPRESSION_FLAG_SNAPPY 1
+struct swarmkv_net_header
+{
+ uint16_t magic;
+ uint8_t version;
+ uint8_t compression_flag; // COMPRESSION_FLAG_XX
+ uint64_t ts_val; // TS Value in usec
+ uint64_t ts_ecr; // TS Echo Reply in usec
+ int src_tid;
+ int dst_tid;
+ uint32_t payload_len;
+};
+#define SWARMKV_NET_HDR_SIZE sizeof(struct swarmkv_net_header)
enum receive_state
{
- RECEIVING_HDR=0,
+ RECEIVING_HDR = 0,
RECEIVING_PAYLOAD
};
struct snet_conn
{
- node_t peer_listen_addr;
- node_t connected_from;
+ node_t peer;
int thread_id;
int need_to_be_kill;
long long ts_ecr;
- enum receive_state recv_state;
- const struct swarmkv_msg *receiving_hdr;//pointer of receiving buffer
+ enum receive_state recv_state;
+ size_t receiving_msg_size;
+ struct evbuffer *buff_for_sending;
int is_in_conn_table;
- int is_duplicated;
- struct evbuffer* buff_for_sending;
pthread_mutex_t mutex;
struct bufferevent *bev;
- evutil_socket_t fd;
+ evutil_socket_t fd;
struct snet_thread *ref_thr;
UT_hash_handle hh;
};
@@ -56,6 +71,7 @@ struct snet_stat
{
long long input_msgs, output_msgs;
long long input_bytes, output_bytes;
+ long long uncompressed_input_bytes, uncompressed_output_bytes;
long long input_buffer_sz, output_buffer_sz;
long long output_drop_msgs;
long long input_error_msgs;
@@ -66,9 +82,7 @@ struct snet_thread
int is_dispatching;
struct event_base *evbase;
struct snet_conn *conn_table;
- struct snet_conn *duplicated_conn_table;
- struct snet_conn *designated_conn;//for sending reply
- long long peer_timeout_us;
+ long long peer_timeout_us;
void *ref_logger;
struct swarmkv_net *ref_net;
@@ -77,18 +91,21 @@ struct snet_thread
};
struct swarmkv_net
{
- size_t nr_threads;
+ size_t nr_worker_threads;
+ size_t nr_caller_threads;
+ size_t nr_total_threads;
uuid_t my_uuid;
int n_connection;
+ int do_compression;
node_t self;
struct snet_thread *threads;
-
- struct evconnlistener *listener;
- void* logger;
- on_msg_callback_t *on_msg_cb;
+ struct evconnlistener *listener;
+
+ void *logger;
+ on_net_msg_callback_t *on_msg_cb;
void *on_msg_cb_arg;
- struct event * stat_ev;
+ struct event *stat_ev;
long long last_input_bytes, last_output_bytes;
long long last_input_msgs, last_output_msgs;
struct timespec last_stats;
@@ -103,49 +120,47 @@ static void peer_conn_event_cb(struct bufferevent *bev, short events, void *arg)
struct snet_conn *snet_conn_new_by_connecting(struct snet_thread *thr, const node_t *dest)
{
- struct snet_conn *conn=ALLOC(struct snet_conn, 1);
- conn->buff_for_sending=evbuffer_new();
- conn->fd=-1;
-
- //http://www.wangafu.net/~nickm/libevent-book/Ref6_bufferevent.html
- conn->bev=bufferevent_socket_new(thr->evbase, -1, BEV_OPT_DEFER_CALLBACKS|BEV_OPT_UNLOCK_CALLBACKS);//BEV_OPT_UNLOCK_CALLBACKS|BEV_OPT_THREADSAFE
+ struct snet_conn *conn = ALLOC(struct snet_conn, 1);
+ conn->buff_for_sending = evbuffer_new();
+ conn->fd = -1;
+
+ // http://www.wangafu.net/~nickm/libevent-book/Ref6_bufferevent.html
+ conn->bev = bufferevent_socket_new(thr->evbase, -1, BEV_OPT_DEFER_CALLBACKS | BEV_OPT_UNLOCK_CALLBACKS); // BEV_OPT_UNLOCK_CALLBACKS|BEV_OPT_THREADSAFE
bufferevent_setcb(conn->bev, NULL, NULL, peer_connected_event_cb, conn);
- node_copy(&conn->peer_listen_addr, dest);
- conn->thread_id=thr->thread_id;
- conn->ref_thr=thr;
- node_copy(&conn->connected_from, dest);
+ node_copy(&conn->peer, dest);
+ conn->thread_id = thr->thread_id;
+ conn->ref_thr = thr;
struct sockaddr sa;
node_to_sockaddr(dest, &sa);
if (bufferevent_socket_connect(conn->bev, &sa, sizeof(sa)) < 0)
{
- bufferevent_free(conn->bev);
+ bufferevent_free(conn->bev);
goto error_out;
- }
+ }
return conn;
error_out:
evbuffer_free(conn->buff_for_sending);
- conn->buff_for_sending=NULL;
+ conn->buff_for_sending = NULL;
free(conn);
return NULL;
-
}
-struct snet_conn *snet_conn_new_by_fd(struct snet_thread *thr, evutil_socket_t fd, const node_t *peer)
+struct snet_conn *snet_conn_new_by_accepted(struct snet_thread *thr, evutil_socket_t fd, const node_t *peer)
{
- struct snet_conn *conn=ALLOC(struct snet_conn, 1);
- conn->buff_for_sending=evbuffer_new();
- int yes=1;
- setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes));
-// evbuffer_enable_locking(conn->buff_for_sending, NULL);
+ struct snet_conn *conn = ALLOC(struct snet_conn, 1);
+ conn->buff_for_sending = evbuffer_new();
+ int yes = 1;
+ setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof(yes));
+ // evbuffer_enable_locking(conn->buff_for_sending, NULL);
evutil_make_socket_nonblocking(fd);
evutil_make_socket_closeonexec(fd);
- node_copy(&conn->connected_from, peer);
- conn->bev=bufferevent_socket_new(thr->evbase, fd, BEV_OPT_DEFER_CALLBACKS|BEV_OPT_UNLOCK_CALLBACKS);//BEV_OPT_UNLOCK_CALLBACKS|BEV_OPT_THREADSAFE
- //use BEV_OPT_THREADSAFE option for safely access from threads that calling swarmkv_net_send.
+ conn->bev = bufferevent_socket_new(thr->evbase, fd, BEV_OPT_DEFER_CALLBACKS | BEV_OPT_UNLOCK_CALLBACKS); // BEV_OPT_UNLOCK_CALLBACKS|BEV_OPT_THREADSAFE
+ // use BEV_OPT_THREADSAFE option for safely access from threads that calling swarmkv_net_send.
//? use BEV_OPT_UNLOCK_CALLBACKS option because swarmkv_net_send write buffer to output_buffer, and peer_conn_read_cb read input_buffer.
- conn->fd=fd;
- conn->thread_id=thr->thread_id;
- conn->ref_thr=thr;
+ conn->fd = fd;
+ conn->thread_id = thr->thread_id;
+ conn->ref_thr = thr;
+ node_copy(&conn->peer, peer);
bufferevent_setcb(conn->bev, peer_conn_read_cb, peer_conn_write_cb, peer_conn_event_cb, conn);
bufferevent_enable(conn->bev, EV_READ | EV_WRITE);
return conn;
@@ -153,155 +168,133 @@ struct snet_conn *snet_conn_new_by_fd(struct snet_thread *thr, evutil_socket_t f
static void snet_conn_table_remove(struct snet_conn *conn)
{
- struct snet_thread *thr=conn->ref_thr;
- if(conn->is_in_conn_table)
- {
- HASH_DEL(thr->conn_table, conn);
- conn->is_in_conn_table=0;
- }
- else if(conn->is_duplicated)
- {
- HASH_DEL(thr->duplicated_conn_table, conn);
- conn->is_duplicated=0;
- }
- return;
-}
-static void snet_conn_buffer_size(struct snet_conn *conn, long long *input_buff_sz, long long *output_buff_sz)
-{
- struct evbuffer *tmp=NULL;
- if(conn->bev)
- {
- tmp=bufferevent_get_input(conn->bev);
- *input_buff_sz=evbuffer_get_length(tmp);
- tmp=bufferevent_get_output(conn->bev);
- *output_buff_sz=evbuffer_get_length(tmp);
- }
- else
- {
- *input_buff_sz=0;
- *output_buff_sz=evbuffer_get_length(conn->buff_for_sending);
- }
+ struct snet_thread *thr = conn->ref_thr;
+ assert(conn->is_in_conn_table);
+
+ HASH_DEL(thr->conn_table, conn);
+ conn->is_in_conn_table = 0;
+
return;
}
+
static void snet_conn_free(struct snet_conn *conn)
{
evbuffer_free(conn->buff_for_sending);
- conn->buff_for_sending=NULL;
- if(conn->bev)
+ conn->buff_for_sending = NULL;
+ if (conn->bev)
{
bufferevent_disable(conn->bev, EV_READ | EV_WRITE);
bufferevent_free(conn->bev);
}
- if(conn->fd>0)
+ if (conn->fd > 0)
{
evutil_closesocket(conn->fd);
- conn->fd=-1;
+ conn->fd = -1;
}
- assert(!conn->is_in_conn_table && !conn->is_duplicated);
+ assert(!conn->is_in_conn_table);
free(conn);
return;
}
-/*
-static void swarmkv_connection_kill(struct snet_conn *conn)
-{
- conn->need_to_be_kill=1;
- bufferevent_trigger(conn->bev, EV_READ, BEV_TRIG_IGNORE_WATERMARKS);
- return;
-}
-*/
-static void snet_conn_set_peer(struct snet_conn *conn, node_t *peer)
-{
- node_copy(&conn->peer_listen_addr, peer);
- return;
-}
static void snet_conn_table_add(struct snet_thread *thr, struct snet_conn *conn)
{
- struct snet_conn *tmp_conn=NULL;
- assert(conn->is_in_conn_table==0);
- HASH_FIND(hh, thr->conn_table, &(conn->peer_listen_addr), sizeof(node_t), tmp_conn);
+ struct snet_conn *tmp_conn = NULL;
+ assert(conn->is_in_conn_table == 0);
+ HASH_FIND(hh, thr->conn_table, &(conn->peer), sizeof(node_t), tmp_conn);
if(tmp_conn)
{
- //Simultaneous open
- log_fatal(thr->ref_logger, MODULE_SWAMRKV_NET,
- "accept duplicated connection from peer %s, existed connection is %s.",
- conn->connected_from.addr,
- tmp_conn->connected_from.addr);
- conn->is_duplicated=1;
- HASH_ADD(hh, thr->duplicated_conn_table, peer_listen_addr, sizeof(conn->peer_listen_addr), conn);
- //snet_conn_table_remove(tmp_conn);
- //swarmkv_connection_kill(tmp_conn);
- }
- else
- {
- HASH_ADD(hh, thr->conn_table, peer_listen_addr, sizeof(conn->peer_listen_addr), conn);
- conn->is_in_conn_table=1;
- log_info(thr->ref_logger, MODULE_SWAMRKV_NET,
- "new peer connection from %s has been set, which is connected from %s.",
- conn->peer_listen_addr.addr,
- conn->connected_from.addr);
+ log_fatal(thr->ref_logger, MODULE_SWAMRKV_NET, "connection %s is killed for duplication address",
+ node_addr2cstr(&tmp_conn->peer));
+ snet_conn_table_remove(tmp_conn);
+ snet_conn_free(tmp_conn);
}
+
+ HASH_ADD(hh, thr->conn_table, peer, sizeof(conn->peer), conn);
+ conn->is_in_conn_table = 1;
+ log_info(thr->ref_logger, MODULE_SWAMRKV_NET,
+ "new peer connection from %s has been recorded.",
+ node_addr2cstr(&conn->peer));
return;
}
static void peer_conn_write_cb(struct bufferevent *bev, void *arg)
{
- struct snet_conn *conn=(struct snet_conn*)arg;
+ struct snet_conn *conn = (struct snet_conn *)arg;
bufferevent_write_buffer(conn->bev, conn->buff_for_sending);
return;
}
+static void snet_conn_buffer_size(struct snet_conn *conn, long long *input_buff_sz, long long *output_buff_sz)
+{
+ struct evbuffer *tmp = NULL;
+ if (conn->bev)
+ {
+ tmp = bufferevent_get_input(conn->bev);
+ *input_buff_sz = evbuffer_get_length(tmp);
+ tmp = bufferevent_get_output(conn->bev);
+ *output_buff_sz = evbuffer_get_length(tmp);
+ }
+ else
+ {
+ *input_buff_sz = 0;
+ *output_buff_sz = evbuffer_get_length(conn->buff_for_sending);
+ }
+ return;
+}
void snet_thread_buffer_usage_stat(struct snet_thread *thr)
{
- long long total_input_sz=0, total_output_sz=0;
- long long input_sz=0, output_sz=0;
- struct snet_conn *conn=NULL, *tmp=NULL;
+ long long total_input_sz = 0, total_output_sz = 0;
+ long long input_sz = 0, output_sz = 0;
+ struct snet_conn *conn = NULL, *tmp = NULL;
HASH_ITER(hh, thr->conn_table, conn, tmp)
{
snet_conn_buffer_size(conn, &input_sz, &output_sz);
- total_input_sz+=input_sz;
- total_output_sz+=output_sz;
+ total_input_sz += input_sz;
+ total_output_sz += output_sz;
}
- thr->stat.output_buffer_sz=total_output_sz;
- thr->stat.input_buffer_sz=total_input_sz;
+ thr->stat.output_buffer_sz = total_output_sz;
+ thr->stat.input_buffer_sz = total_input_sz;
return;
}
static void peer_conn_read_cb(struct bufferevent *bev, void *arg)
{
- struct snet_conn *conn=(struct snet_conn*)arg;
- struct snet_thread *thr=conn->ref_thr;
- assert(0==evbuffer_get_length(conn->buff_for_sending));
- struct evbuffer *input = bufferevent_get_input(bev);
- assert(bev==conn->bev);
- snet_thread_buffer_usage_stat(thr);
- assert(conn->ref_thr == conn->ref_thr->ref_net->threads+conn->thread_id);
- struct swarmkv_msg *msg=NULL;
- if(conn->need_to_be_kill)
+ struct snet_conn *conn = (struct snet_conn *)arg;
+ struct snet_thread *thr = conn->ref_thr;
+ assert(0 == evbuffer_get_length(conn->buff_for_sending));
+ struct evbuffer *input = bufferevent_get_input(bev);
+ assert(bev == conn->bev);
+
+ assert(conn->ref_thr == conn->ref_thr->ref_net->threads + conn->thread_id);
+ snet_thread_buffer_usage_stat(thr);
+ if (conn->need_to_be_kill)
{
log_fatal(thr->ref_logger, MODULE_SWAMRKV_NET, "connection %s is killed",
- conn->connected_from.addr);
- assert(conn->is_in_conn_table==0);
+ node_addr2cstr(&conn->peer));
+ assert(conn->is_in_conn_table == 0);
snet_conn_free(conn);
return;
}
- const char *recv_buff=NULL;
- struct swarmkv_msg* hdr=NULL;
- while(1)
+
+ while (1)
{
- if(conn->recv_state==RECEIVING_HDR)
+ const char *recv_buff = NULL;
+ struct swarmkv_net_header *hdr = NULL;
+ size_t uncompressed_length = 0;
+ if (conn->recv_state == RECEIVING_HDR)
{
- recv_buff=(const char*) evbuffer_pullup(input, SWARMKV_MSG_HDR_SIZE);
- if(!recv_buff)
+ assert(conn->receiving_msg_size == 0);
+ recv_buff = (const char *)evbuffer_pullup(input, SWARMKV_NET_HDR_SIZE);
+ if (!recv_buff)
{
- bufferevent_setwatermark(bev, EV_READ, SWARMKV_MSG_HDR_SIZE, 0);
- conn->recv_state=RECEIVING_HDR;
+ bufferevent_setwatermark(bev, EV_READ, SWARMKV_NET_HDR_SIZE, 0);
+ conn->recv_state = RECEIVING_HDR;
break;
}
- hdr = (struct swarmkv_msg*) recv_buff;
- if(hdr->magic != SWARMKV_MSG_MAGIC)
+ hdr = (struct swarmkv_net_header *)recv_buff;
+ if (hdr->magic != SWARMKV_NET_HDR_MAGIC)
{
log_fatal(thr->ref_logger, MODULE_SWAMRKV_NET, "invalid message header magic from %s",
- conn->connected_from.addr);
- if(conn->is_in_conn_table)
+ node_addr2cstr(&conn->peer));
+ if (conn->is_in_conn_table)
{
snet_conn_table_remove(conn);
}
@@ -309,129 +302,166 @@ static void peer_conn_read_cb(struct bufferevent *bev, void *arg)
thr->stat.input_error_msgs++;
break;
}
- if(!conn->is_in_conn_table && !conn->is_duplicated)
+ if (!conn->is_in_conn_table)
{
- snet_conn_set_peer(conn, &hdr->caller);
- snet_conn_table_add(thr, conn);
+ snet_conn_table_add(thr, conn);
}
- conn->ts_ecr=hdr->ts_val;
- conn->recv_state=RECEIVING_PAYLOAD;
- conn->receiving_hdr=(struct swarmkv_msg *)recv_buff;
- long long now_us=ustime();
- if(hdr->ts_ecr && now_us > hdr->ts_ecr)
+ conn->ts_ecr = hdr->ts_val;
+ conn->recv_state = RECEIVING_PAYLOAD;
+ conn->receiving_msg_size = SWARMKV_NET_HDR_SIZE + hdr->payload_len;
+ long long now_us = ustime();
+ if (hdr->ts_ecr && now_us > hdr->ts_ecr)
{
- //If now_us < hdr->ts_ecr, may be manually time adjustment
- swarmkv_monitor_record_peer(thr->mod_monitor, &conn->peer_listen_addr, now_us-hdr->ts_ecr, thr->thread_id);
+ // If now_us < hdr->ts_ecr, may be manually time adjustment
+ swarmkv_monitor_record_peer(thr->mod_monitor, &conn->peer, now_us - hdr->ts_ecr, thr->thread_id);
}
+ hdr = NULL;
}
- if(conn->recv_state==RECEIVING_PAYLOAD)
+ if (conn->recv_state == RECEIVING_PAYLOAD)
{
- size_t msg_sz=SWARMKV_MSG_HDR_SIZE+conn->receiving_hdr->payload_len;
- recv_buff=(const char*)evbuffer_pullup(input, msg_sz);
- if(!recv_buff)//not enough buffer
+ assert(conn->receiving_msg_size > 0);
+ recv_buff = (const char *)evbuffer_pullup(input, conn->receiving_msg_size);
+ if (!recv_buff) // not enough buffer
{
- bufferevent_setwatermark(conn->bev, EV_READ, msg_sz, 0);
- conn->recv_state=RECEIVING_PAYLOAD;
+ bufferevent_setwatermark(conn->bev, EV_READ, conn->receiving_msg_size, 0);
+ conn->recv_state = RECEIVING_PAYLOAD;
break;
}
- msg=swarmkv_msg_deserialize(recv_buff, msg_sz);
- //onwership of msg is transfered to on_msg_cb
- thr->ref_net->on_msg_cb(msg, thr->ref_net->on_msg_cb_arg);
- //swarmkv_msg_free(msg);
- msg=NULL;
- evbuffer_drain(input, msg_sz);
+ hdr = (struct swarmkv_net_header *)recv_buff;
+ if(hdr->version == SWARMKV_NET_HDR_VERSION)
+ {
+ struct swarmkv_msg *msg = NULL;
+ if (hdr->compression_flag == COMPRESSION_FLAG_NONE)
+ {
+ msg = swarmkv_msg_deserialize(recv_buff + SWARMKV_NET_HDR_SIZE, hdr->payload_len);
+ uncompressed_length = hdr->payload_len;
+ }
+ else if (hdr->compression_flag == COMPRESSION_FLAG_SNAPPY)
+ {
+ if (SNAPPY_OK != snappy_uncompressed_length(recv_buff + SWARMKV_NET_HDR_SIZE, hdr->payload_len, &uncompressed_length))
+ {
+ fprintf(stderr, "snappy_uncompressed_length failed\n");
+ assert(0);
+ }
+ char *uncompressed_data = ALLOC(char, uncompressed_length);
+ if (SNAPPY_OK != snappy_uncompress(recv_buff + SWARMKV_NET_HDR_SIZE, hdr->payload_len, uncompressed_data, &uncompressed_length))
+ {
+ fprintf(stderr, "snappy_uncompress failed\n");
+ assert(0);
+ }
+ msg = swarmkv_msg_deserialize(uncompressed_data, uncompressed_length);
+ free(uncompressed_data);
+ }
+ else
+ {
+ assert(0);
+ }
+
+ // onwership of msg is transfered to on_msg_cb
+ thr->ref_net->on_msg_cb(msg, &conn->peer, hdr->src_tid, thr->ref_net->on_msg_cb_arg);
+ msg = NULL;
+ }
+ else
+ {
+ thr->stat.input_error_msgs++;
+ }
thr->stat.input_msgs++;
- thr->stat.input_bytes += msg_sz;
- conn->recv_state=RECEIVING_HDR;
+ thr->stat.input_bytes += conn->receiving_msg_size;
+ thr->stat.uncompressed_input_bytes += (SWARMKV_NET_HDR_SIZE + uncompressed_length);
+ evbuffer_drain(input, conn->receiving_msg_size);
+ conn->recv_state = RECEIVING_HDR;
+ conn->receiving_msg_size = 0;
}
}
return;
}
static void peer_conn_event_cb(struct bufferevent *bev, short events, void *arg)
{
- struct snet_conn *conn=(struct snet_conn*)arg;
- struct snet_thread *thr=conn->ref_thr;
-
+ struct snet_conn *conn = (struct snet_conn *)arg;
+ struct snet_thread *thr = conn->ref_thr;
+ long long input_buffer_sz = 0, output_buffer_sz = 0;
+ snet_conn_buffer_size(conn, &input_buffer_sz, &output_buffer_sz);
int err = EVUTIL_SOCKET_ERROR();
if (events & BEV_EVENT_ERROR || events & BEV_EVENT_EOF)
{
- log_debug(thr->ref_logger, MODULE_SWAMRKV_NET, "%s connection error, %d (%s).",
- conn->connected_from.addr,
- err, evutil_socket_error_to_string(err));
- //swarmkv-cli's connection has listen port number > 10000.
+ log_debug(thr->ref_logger, MODULE_SWAMRKV_NET, "closing connection %s, error: %d (%s), unprocessed in/out bytes %lld / %lld.",
+ node_addr2cstr(&conn->peer),
+ err, evutil_socket_error_to_string(err),
+ input_buffer_sz, output_buffer_sz);
+ // swarmkv-cli's connection has listen port number > 10000.
}
-
+
snet_conn_table_remove(conn);
snet_conn_free(conn);
return;
}
void peer_connected_event_cb(struct bufferevent *bev, short events, void *arg)
{
- struct snet_conn* conn= (struct snet_conn*) arg;
- struct snet_thread* thr=conn->ref_thr;
-
- assert(bev==conn->bev);
+ struct snet_conn *conn = (struct snet_conn *)arg;
+ struct snet_thread *thr = conn->ref_thr;
+
+ assert(bev == conn->bev);
if (events & BEV_EVENT_CONNECTED)
{
- int yes=1;
- evutil_socket_t fd=bufferevent_getfd(conn->bev);
- setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes));
- conn->fd=fd;
+ int yes = 1;
+ evutil_socket_t fd = bufferevent_getfd(conn->bev);
+ setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof(yes));
+ conn->fd = fd;
evutil_make_socket_closeonexec(fd);
bufferevent_write_buffer(conn->bev, conn->buff_for_sending);
bufferevent_setcb(conn->bev, peer_conn_read_cb, peer_conn_write_cb, peer_conn_event_cb, conn);
bufferevent_enable(conn->bev, EV_READ | EV_WRITE);
log_debug(thr->ref_logger, MODULE_SWAMRKV_NET, "peer %s is connected.",
- conn->peer_listen_addr.addr);
- }
+ conn->peer.addr);
+ }
else if (events & BEV_EVENT_ERROR)
- {
+ {
int err = EVUTIL_SOCKET_ERROR();
log_fatal(thr->ref_logger, MODULE_SWAMRKV_NET, "connect to %s failed %d (%s).",
- conn->peer_listen_addr.addr,
- err, evutil_socket_error_to_string(err));
- if(conn->fd<=0)
- {
- evutil_socket_t fd=bufferevent_getfd(conn->bev);
- conn->fd=fd;
- }
+ conn->peer.addr,
+ err, evutil_socket_error_to_string(err));
+ if (conn->fd <= 0)
+ {
+ evutil_socket_t fd = bufferevent_getfd(conn->bev);
+ conn->fd = fd;
+ }
snet_conn_table_remove(conn);
snet_conn_free(conn);
- }
+ }
}
-static void snet_stat_periodic(evutil_socket_t fd, short what, void * arg)
+static void snet_stat_periodic(evutil_socket_t fd, short what, void *arg)
{
- struct swarmkv_net *net= (struct swarmkv_net *)arg;
+ struct swarmkv_net *net = (struct swarmkv_net *)arg;
struct timespec now;
- long long input_bytes=0, output_bytes=0;
- long long input_msgs=0, output_msgs=0;
+ long long input_bytes = 0, output_bytes = 0;
+ long long input_msgs = 0, output_msgs = 0;
clock_gettime(CLOCK_MONOTONIC, &now);
- if(now.tv_sec == net->last_stats.tv_sec)
+ if (now.tv_sec == net->last_stats.tv_sec)
{
- //The stat interval is too short.
+ // The stat interval is too short.
return;
}
- for(size_t i=0; i<net->nr_threads; i++)
+ for (size_t i = 0; i < net->nr_total_threads; i++)
{
input_bytes += net->threads[i].stat.input_bytes;
output_bytes += net->threads[i].stat.output_bytes;
input_msgs += net->threads[i].stat.input_msgs;
output_msgs += net->threads[i].stat.output_msgs;
}
-
- long long diff_sec=MAX(now.tv_sec - net->last_stats.tv_sec, 1);
- net->instantaneous_input_kbps=(input_bytes - net->last_input_bytes)*8/1000/diff_sec;
- net->instantaneous_output_kbps=(output_bytes - net->last_output_bytes)*8/1000/diff_sec;
- net->instantaneous_input_msgs=(input_msgs - net->last_input_msgs)/diff_sec;
- net->instantaneous_output_msgs=(output_msgs - net->last_output_msgs)/diff_sec;
+
+ long long diff_sec = MAX(now.tv_sec - net->last_stats.tv_sec, 1);
+ net->instantaneous_input_kbps = (input_bytes - net->last_input_bytes) * 8 / 1000 / diff_sec;
+ net->instantaneous_output_kbps = (output_bytes - net->last_output_bytes) * 8 / 1000 / diff_sec;
+ net->instantaneous_input_msgs = (input_msgs - net->last_input_msgs) / diff_sec;
+ net->instantaneous_output_msgs = (output_msgs - net->last_output_msgs) / diff_sec;
clock_gettime(CLOCK_MONOTONIC, &net->last_stats);
- net->last_input_bytes=input_bytes;
- net->last_output_bytes=output_bytes;
- net->last_input_msgs=input_msgs;
- net->last_output_msgs=output_msgs;
+ net->last_input_bytes = input_bytes;
+ net->last_output_bytes = output_bytes;
+ net->last_input_msgs = input_msgs;
+ net->last_output_msgs = output_msgs;
return;
}
@@ -442,105 +472,110 @@ struct peek_msg_hdr_ctx
node_t peer;
int retry;
};
-void peek_msg_hdr_cb(evutil_socket_t fd, short what, void * arg)
+void peek_msg_hdr_cb(evutil_socket_t fd, short what, void *arg)
{
- struct peek_msg_hdr_ctx *ctx=(struct peek_msg_hdr_ctx*) arg;
+ struct peek_msg_hdr_ctx *ctx = (struct peek_msg_hdr_ctx *)arg;
struct swarmkv_net *net = ctx->ref_net;
- unsigned char buf[SWARMKV_MSG_HDR_SIZE];
+ unsigned char buf[SWARMKV_NET_HDR_SIZE];
ssize_t n = 0;
n = recv(fd, buf, sizeof(buf), MSG_PEEK);
- if(n!=sizeof(buf))
+ if (n != sizeof(buf))
{
ctx->retry++;
- if(ctx->retry<3) return;
+ if (ctx->retry < 3)
+ return;
log_error(net->logger, MODULE_SWAMRKV_NET, "peek message header of connection from %s failed.",
- ctx->peer.addr);
+ ctx->peer.addr);
goto failed;
}
- struct swarmkv_msg *hdr=(struct swarmkv_msg *)buf;
- int tid=hdr->caller_tid%net->nr_threads;
- struct snet_thread *thr=net->threads+tid;
- struct snet_conn *conn=NULL;
- conn=snet_conn_new_by_fd(thr, fd, &ctx->peer);
- //Assign a connection to the thread, but for thread safety, do not add it to the table.
- //Instead, add it during the peer_conn_read_cb() function call.
+ struct swarmkv_net_header *hdr = (struct swarmkv_net_header *)buf;
+ //For reply messgage, dst_tid is specified (>=0), then add the connection to the specified destination thread.
+ int tid = (hdr->dst_tid >= 0 ? hdr->dst_tid : random()) % net->nr_worker_threads;
+ struct snet_thread *thr = net->threads + tid;
+ struct snet_conn *conn = NULL;
+ conn = snet_conn_new_by_accepted(thr, fd, &ctx->peer);
+ // For thread safety, do not add it to the table.
+ // Instead, add it during the peer_conn_read_cb() function call.
log_debug(net->logger, MODULE_SWAMRKV_NET, "thread %d accept connection from %s (tid=%d).",
- conn->thread_id, conn->connected_from.addr, hdr->caller_tid);
+ conn->thread_id, node_addr2cstr(&conn->peer), hdr->src_tid);
failed:
event_del(ctx->ev);
event_free(ctx->ev);
free(ctx);
}
-static void accept_peer_connection_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr * addr, int socklen, void *arg)
+static void accept_peer_connection_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *addr, int socklen, void *arg)
{
- struct swarmkv_net *net = (struct swarmkv_net*) arg;
- struct peek_msg_hdr_ctx *ctx=ALLOC(struct peek_msg_hdr_ctx, 1);
- ctx->ref_net=net;
+ struct swarmkv_net *net = (struct swarmkv_net *)arg;
+ struct peek_msg_hdr_ctx *ctx = ALLOC(struct peek_msg_hdr_ctx, 1);
+ ctx->ref_net = net;
node_init_from_sockaddr(&ctx->peer, addr);
- ctx->ev = event_new(net->threads[0].evbase, fd, EV_READ|EV_PERSIST, peek_msg_hdr_cb, ctx);
+ ctx->ev = event_new(net->threads[0].evbase, fd, EV_READ | EV_PERSIST, peek_msg_hdr_cb, ctx);
event_add(ctx->ev, NULL);
return;
}
static void __accept_error_cb(struct evconnlistener *listener, void *arg)
{
- struct swarmkv_net *net = (struct swarmkv_net*) arg;
- int err = EVUTIL_SOCKET_ERROR();
+ struct swarmkv_net *net = (struct swarmkv_net *)arg;
+ int err = EVUTIL_SOCKET_ERROR();
log_fatal(net->logger, MODULE_SWAMRKV_NET, "accept peer connection failed %d (%s).",
- err, evutil_socket_error_to_string(err));
+ err, evutil_socket_error_to_string(err));
}
-#define MAX_OUTPUT_BUFFER_SIZE 1024*1024*64
+#define MAX_OUTPUT_BUFFER_SIZE 1024 * 1024 * 64
struct swarmkv_net *swarmkv_net_new(struct event_base *evbases[], int nr_threads, struct swarmkv_options *opts, struct log_handle *logger, char **err)
{
- struct swarmkv_net *net=NULL;
- net=ALLOC(struct swarmkv_net, 1);
- net->logger=logger;
- net->nr_threads=nr_threads;
- net->threads=ALLOC(struct snet_thread, net->nr_threads);
- struct snet_thread *thr=NULL;
-
- for(size_t i=0; i<net->nr_threads; i++)
+ struct swarmkv_net *net = NULL;
+ net = ALLOC(struct swarmkv_net, 1);
+ net->logger = logger;
+ net->nr_total_threads = opts->total_threads;
+ net->nr_caller_threads = opts->nr_caller_threads;
+ net->nr_worker_threads = opts->nr_worker_threads;
+ net->do_compression = opts->network_compression_enabled;
+ net->threads = ALLOC(struct snet_thread, net->nr_total_threads);
+ struct snet_thread *thr = NULL;
+
+ for (size_t i = 0; i < net->nr_total_threads; i++)
{
- thr=net->threads+i;
- thr->evbase=evbases[i];
- thr->thread_id=i;
- thr->peer_timeout_us=opts->cluster_timeout_us;
- thr->ref_logger=logger;
- thr->ref_net=net;
- thr->conn_table=NULL;
+ thr = net->threads + i;
+ thr->evbase = evbases[i];
+ thr->thread_id = i;
+ thr->peer_timeout_us = opts->cluster_timeout_us;
+ thr->ref_logger = logger;
+ thr->ref_net = net;
+ thr->conn_table = NULL;
}
net->stat_ev = event_new(evbases[0], -1, EV_PERSIST, snet_stat_periodic, net);
struct timeval timer_delay = {2, 0};
evtimer_add(net->stat_ev, &timer_delay);
-
- //Refer to http://www.wangafu.net/~nickm/libevent-book/Ref8_listener.html
+
+ // Refer to http://www.wangafu.net/~nickm/libevent-book/Ref8_listener.html
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
inet_pton(AF_INET, opts->bind_address, &(sin.sin_addr));
sin.sin_port = htons((unsigned short)opts->cluster_port);
- net->listener=evconnlistener_new_bind(net->threads[0].evbase, accept_peer_connection_cb, net,
- LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1, (struct sockaddr*)&sin, sizeof(sin));
- if(!net->listener)
+ net->listener = evconnlistener_new_bind(net->threads[0].evbase, accept_peer_connection_cb, net,
+ LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1, (struct sockaddr *)&sin, sizeof(sin));
+ if (!net->listener)
{
asprintf(err, "listen on port %u failed", opts->cluster_port);
free(net);
return NULL;
}
evconnlistener_set_error_cb(net->listener, __accept_error_cb);
- int sockfd=evconnlistener_get_fd(net->listener);
- struct sockaddr_storage ss;
+ int sockfd = evconnlistener_get_fd(net->listener);
+ struct sockaddr_storage ss;
ev_socklen_t socklen = sizeof(ss);
if (getsockname(sockfd, (struct sockaddr *)&ss, &socklen) < 0)
{
asprintf(err, "getsockname failed");
}
- opts->cluster_port=ntohs(((struct sockaddr_in*)&ss)->sin_port);
- if(opts->cluster_announce_port==0)
+ opts->cluster_port = ntohs(((struct sockaddr_in *)&ss)->sin_port);
+ if (opts->cluster_announce_port == 0)
{
- opts->cluster_announce_port=opts->cluster_port;
+ opts->cluster_announce_port = opts->cluster_port;
}
node_init(&net->self, opts->cluster_announce_ip, opts->cluster_announce_port);
@@ -548,13 +583,14 @@ struct swarmkv_net *swarmkv_net_new(struct event_base *evbases[], int nr_threads
}
void swarmkv_net_info(struct swarmkv_net *net, struct snet_info *info)
{
- struct snet_thread *thr=NULL;
+ struct snet_thread *thr = NULL;
memset(info, 0, sizeof(struct snet_info));
- info->output_buf_max=MAX_OUTPUT_BUFFER_SIZE;
- for(size_t i=0; i<net->nr_threads; i++)
+ info->output_buf_max = MAX_OUTPUT_BUFFER_SIZE;
+ long long uncompressed_input_bytes = 0, uncompressed_output_bytes = 0;
+ for (size_t i = 0; i < net->nr_total_threads; i++)
{
- thr=net->threads+i;
- info->connections += (HASH_COUNT(thr->conn_table) + HASH_COUNT(thr->duplicated_conn_table));
+ thr = net->threads + i;
+ info->connections += HASH_COUNT(thr->conn_table);
info->input_bytes += thr->stat.input_bytes;
info->input_msgs += thr->stat.input_msgs;
@@ -565,36 +601,35 @@ void swarmkv_net_info(struct swarmkv_net *net, struct snet_info *info)
info->input_buffer_sz += thr->stat.input_buffer_sz;
info->output_buffer_sz += thr->stat.output_buffer_sz;
info->output_drop_msgs += thr->stat.output_drop_msgs;
+ uncompressed_input_bytes += thr->stat.uncompressed_input_bytes;
+ uncompressed_output_bytes += thr->stat.uncompressed_output_bytes;
}
- info->instantaneous_input_kbps=net->instantaneous_input_kbps;
- info->instantaneous_output_kbps=net->instantaneous_output_kbps;
- info->instantaneous_input_msgs=net->instantaneous_input_msgs;
- info->instantaneous_output_msgs=net->instantaneous_output_msgs;
+ info->instantaneous_input_kbps = net->instantaneous_input_kbps;
+ info->instantaneous_output_kbps = net->instantaneous_output_kbps;
+ info->instantaneous_input_msgs = net->instantaneous_input_msgs;
+ info->instantaneous_output_msgs = net->instantaneous_output_msgs;
+ info->input_compression_ratio = (double)info->input_bytes / uncompressed_input_bytes;
+ info->output_compression_ratio = (double)info->output_bytes / uncompressed_output_bytes;
return;
}
void swarmkv_net_free(struct swarmkv_net *net)
{
- int i=0;
- struct snet_thread *thr=NULL;
- struct snet_conn *conn=NULL, *tmp=NULL;
+ int i = 0;
+ struct snet_thread *thr = NULL;
+ struct snet_conn *conn = NULL, *tmp = NULL;
evconnlistener_free(net->listener);
- for(i=0; i<net->nr_threads; i++)
- {
- thr=net->threads+i;
+ for (i = 0; i < net->nr_total_threads; i++)
+ {
+ thr = net->threads + i;
HASH_ITER(hh, thr->conn_table, conn, tmp)
{
snet_conn_table_remove(conn);
snet_conn_free(conn);
}
- HASH_ITER(hh, thr->duplicated_conn_table, conn, tmp)
- {
- snet_conn_table_remove(conn);
- snet_conn_free(conn);
- }
- thr->evbase=NULL;
+ thr->evbase = NULL;
}
event_del(net->stat_ev);
event_free(net->stat_ev);
@@ -605,64 +640,95 @@ void swarmkv_net_free(struct swarmkv_net *net)
}
void swarmkv_net_set_monitor_handle(struct swarmkv_net *net, struct swarmkv_module *mod_monitor)
{
- for(size_t i=0; i<net->nr_threads; i++)
+ for (size_t i = 0; i < net->nr_total_threads; i++)
{
- net->threads[i].mod_monitor=mod_monitor;
+ net->threads[i].mod_monitor = mod_monitor;
}
}
-void swarmkv_net_set_on_msg_callback(struct swarmkv_net *net, on_msg_callback_t *cb, void *cb_arg)
+void swarmkv_net_set_on_msg_callback(struct swarmkv_net *net, on_net_msg_callback_t *cb, void *cb_arg)
{
- net->on_msg_cb=cb;
- net->on_msg_cb_arg=cb_arg;
+ net->on_msg_cb = cb;
+ net->on_msg_cb_arg = cb_arg;
return;
}
-int swarmkv_net_send(struct swarmkv_net *net, const node_t *dest, struct swarmkv_msg *msg, const char **err_str)
+int swarmkv_net_send(struct swarmkv_net *net, int tid, const node_t *dest, int dest_tid, struct swarmkv_msg *msg, const char **err_str)
{
- int tid=swarmkv_gettid((struct swarmkv *)(net->on_msg_cb_arg));
- assert(tid<net->nr_threads);
- struct snet_thread *thr=net->threads+tid;
- struct snet_conn *conn=NULL;
+ int cur_tid = swarmkv_gettid((struct swarmkv *)(net->on_msg_cb_arg));
+ assert(tid < net->nr_total_threads);
+ assert(cur_tid == tid);
+ struct snet_thread *thr = net->threads + tid;
+ struct snet_conn *conn = NULL;
HASH_FIND(hh, thr->conn_table, dest, sizeof(node_t), conn);
- if(!conn)
+ if (!conn)
{
- conn=snet_conn_new_by_connecting(thr, dest);
- if(conn)
+ conn = snet_conn_new_by_connecting(thr, dest);
+ if (conn)
{
- HASH_ADD(hh, thr->conn_table, peer_listen_addr, sizeof(node_t), conn);
- conn->is_in_conn_table=1;
+ HASH_ADD(hh, thr->conn_table, peer, sizeof(node_t), conn);
+ conn->is_in_conn_table = 1;
}
else
- {
+ {
int err = EVUTIL_SOCKET_ERROR();
log_fatal(net->logger, MODULE_SWAMRKV_NET, "connect to %s failed, reason %d (%s).",
- dest->addr,
- err, evutil_socket_error_to_string(err));
- *err_str=evutil_socket_error_to_string(err);
+ dest->addr,
+ err, evutil_socket_error_to_string(err));
+ *err_str = evutil_socket_error_to_string(err);
return -1;
}
}
- char *data=NULL;
- size_t size=0;
- msg->ts_val=ustime();
- msg->ts_ecr=conn->ts_ecr;
- swarmkv_msg_serialize(msg, &data, &size);
+ struct swarmkv_net_header hdr;
+ char *data = NULL;
+ size_t size = 0, size_before_compression=0;
+ memset(&hdr, 0, sizeof(hdr));
+ hdr.magic = SWARMKV_NET_HDR_MAGIC;
+ hdr.version = SWARMKV_NET_HDR_VERSION;
+ hdr.ts_val = ustime();
+ hdr.ts_ecr = conn->ts_ecr;
+ hdr.src_tid = tid;
+ hdr.dst_tid = dest_tid;
+ swarmkv_msg_serialize(msg, &data, &size);
swarmkv_msg_free(msg);
- struct evbuffer* output_buffer=NULL;
- output_buffer=bufferevent_get_output(conn->bev);
- if(!output_buffer) output_buffer=conn->buff_for_sending;
- int ret=0;
- if(evbuffer_get_length(output_buffer) + size > MAX_OUTPUT_BUFFER_SIZE)
+ size_before_compression = size;
+ if (net->do_compression)
+ {
+ size_t compressed_length = snappy_max_compressed_length(size);
+ char *compresseed_payload = ALLOC(char, compressed_length);
+ if (SNAPPY_OK != snappy_compress(data, size, compresseed_payload, &compressed_length))
+ {
+ fprintf(stderr, "snappy_compress failed\n");
+ assert(0);
+ }
+ free(data);
+ data = compresseed_payload;
+ size = compressed_length;
+ compresseed_payload = NULL;
+ hdr.compression_flag = COMPRESSION_FLAG_SNAPPY;
+ }
+ else
+ {
+ hdr.compression_flag = COMPRESSION_FLAG_NONE;
+ }
+ hdr.payload_len = size;
+ struct evbuffer *output_buffer = NULL;
+ output_buffer = bufferevent_get_output(conn->bev);
+ if (!output_buffer)
+ output_buffer = conn->buff_for_sending;
+ int ret = 0;
+ if (evbuffer_get_length(output_buffer) + size > MAX_OUTPUT_BUFFER_SIZE)
{
thr->stat.output_drop_msgs++;
- *err_str="output buffer is full";
- ret=-1;
+ *err_str = "output buffer is full";
+ ret = -1;
}
else
{
+ evbuffer_add(output_buffer, &hdr, SWARMKV_NET_HDR_SIZE);
evbuffer_add(output_buffer, data, size);
- thr->stat.output_bytes += size;
- thr->stat.output_msgs ++;
+ thr->stat.output_bytes += (SWARMKV_NET_HDR_SIZE + size);
+ thr->stat.output_msgs++;
+ thr->stat.uncompressed_output_bytes += (SWARMKV_NET_HDR_SIZE + size_before_compression);
}
free(data);
return ret;
diff --git a/src/swarmkv_net.h b/src/swarmkv_net.h
index 87c0dc2..4566654 100644
--- a/src/swarmkv_net.h
+++ b/src/swarmkv_net.h
@@ -7,9 +7,10 @@ struct swarmkv_net;
struct swarmkv_net *swarmkv_net_new(struct event_base *evbases[], int nr_threads, struct swarmkv_options *opts, struct log_handle *logger, char **err);
void swarmkv_net_free(struct swarmkv_net *net);
-void swarmkv_net_set_on_msg_callback(struct swarmkv_net *net, on_msg_callback_t *cb, void *cb_arg);
+typedef void on_net_msg_callback_t(struct swarmkv_msg *msg, const node_t *peer, int peer_tid, void *arg);
+void swarmkv_net_set_on_msg_callback(struct swarmkv_net *net, on_net_msg_callback_t *cb, void *cb_arg);
//swamrkv_net_send takes the ownership of msg.
-int swarmkv_net_send(struct swarmkv_net *net, const node_t *dest, struct swarmkv_msg *msg, const char **err_str);
+int swarmkv_net_send(struct swarmkv_net *net, int tid, const node_t *dest, int dest_tid, struct swarmkv_msg *msg, const char **err_str);
void swarmkv_net_set_monitor_handle(struct swarmkv_net *net, struct swarmkv_module *mod_monitor);
@@ -35,5 +36,8 @@ struct snet_info
double instantaneous_input_msgs;
double instantaneous_output_msgs;
+
+ double input_compression_ratio;
+ double output_compression_ratio;
};
void swarmkv_net_info(struct swarmkv_net *net, struct snet_info *info); \ No newline at end of file
diff --git a/src/swarmkv_rpc.c b/src/swarmkv_rpc.c
index 55d3622..6f5cb86 100644
--- a/src/swarmkv_rpc.c
+++ b/src/swarmkv_rpc.c
@@ -12,9 +12,9 @@ struct swarmkv_rpc
{
unsigned long long sequence;
struct event *timeout_ev;
- struct future * f;
+ struct future *f;
struct timespec start;
- node_t target_peer; //For inter-node rpc
+ node_t target_peer; // For inter-node rpc
int thread_id;
struct swarmkv_rpc_mgr *ref_mgr;
UT_hash_handle hh;
@@ -22,7 +22,7 @@ struct swarmkv_rpc
struct swarmkv_rpc_thr
{
struct swarmkv_rpc *rpc_table;
- struct event_base *evbase; //reference to db->evbases[i]
+ struct event_base *evbase; // reference to db->evbases[i]
const struct timeval *common_timeout;
};
struct swarmkv_rpc_mgr
@@ -32,7 +32,7 @@ struct swarmkv_rpc_mgr
unsigned int default_timeout_us;
struct swarmkv_rpc_thr *threads;
- //stats
+ // stats
long long timed_out_rpcs;
long long unknown_sequence;
};
@@ -40,55 +40,55 @@ void swarmkv_rpc_free(struct swarmkv_rpc *rpc)
{
event_del(rpc->timeout_ev);
event_free(rpc->timeout_ev);
- struct swarmkv_rpc_thr *thr=rpc->ref_mgr->threads+rpc->thread_id;
+ struct swarmkv_rpc_thr *thr = rpc->ref_mgr->threads + rpc->thread_id;
HASH_DELETE(hh, thr->rpc_table, rpc);
free(rpc);
}
struct swarmkv_rpc_mgr *swarmkv_rpc_mgr_new(struct event_base *evbases[], int nr_threads, long long default_timeout_us)
{
- struct swarmkv_rpc_mgr *mgr=ALLOC(struct swarmkv_rpc_mgr, 1);
- mgr->seq_generator=0;
- mgr->nr_worker_threads=nr_threads;
- mgr->default_timeout_us=default_timeout_us;
- mgr->threads=ALLOC(struct swarmkv_rpc_thr, nr_threads);
-
- struct timeval duration={mgr->default_timeout_us/(1000*1000), mgr->default_timeout_us%(1000*1000)};
- struct swarmkv_rpc_thr *thr=NULL;
- for(int i=0; i<nr_threads; i++)
+ struct swarmkv_rpc_mgr *mgr = ALLOC(struct swarmkv_rpc_mgr, 1);
+ mgr->seq_generator = 0;
+ mgr->nr_worker_threads = nr_threads;
+ mgr->default_timeout_us = default_timeout_us;
+ mgr->threads = ALLOC(struct swarmkv_rpc_thr, nr_threads);
+
+ struct timeval duration = {mgr->default_timeout_us / (1000 * 1000), mgr->default_timeout_us % (1000 * 1000)};
+ struct swarmkv_rpc_thr *thr = NULL;
+ for (int i = 0; i < nr_threads; i++)
{
- thr=mgr->threads+i;
- thr->evbase=evbases[i];
- thr->rpc_table=NULL;
- thr->common_timeout=event_base_init_common_timeout(evbases[i], &duration);
+ thr = mgr->threads + i;
+ thr->evbase = evbases[i];
+ thr->rpc_table = NULL;
+ thr->common_timeout = event_base_init_common_timeout(evbases[i], &duration);
}
return mgr;
}
void swarmkv_rpc_mgr_free(struct swarmkv_rpc_mgr *mgr)
{
- struct swarmkv_rpc *rpc=NULL, *tmp=NULL;
- struct swarmkv_rpc_thr *thr=NULL;
- for(int i=0; i<mgr->nr_worker_threads; i++)
+ struct swarmkv_rpc *rpc = NULL, *tmp = NULL;
+ struct swarmkv_rpc_thr *thr = NULL;
+ for (int i = 0; i < mgr->nr_worker_threads; i++)
{
- thr=mgr->threads+i;
+ thr = mgr->threads + i;
HASH_ITER(hh, thr->rpc_table, rpc, tmp)
{
- struct promise *p=future_to_promise(rpc->f);
- promise_failed(p, FUTURE_ERROR_CANCEL, NULL);
+ struct promise *p = future_to_promise(rpc->f);
+ promise_failed(p, FUTURE_ERROR_CANCEL, NULL);
swarmkv_rpc_free(rpc);
}
}
-
+
free(mgr->threads);
free(mgr);
}
static void rpc_timeout_callback(evutil_socket_t fd, short events, void *arg)
-{
- struct swarmkv_rpc *rpc=(struct swarmkv_rpc *)arg;
+{
+ struct swarmkv_rpc *rpc = (struct swarmkv_rpc *)arg;
rpc->ref_mgr->timed_out_rpcs++;
- struct promise *p=future_to_promise(rpc->f);
+ struct promise *p = future_to_promise(rpc->f);
char error_str[128];
- if(!node_is_empty(&rpc->target_peer))
+ if (!node_is_empty(&rpc->target_peer))
{
snprintf(error_str, sizeof(error_str), "peer %s timed out", rpc->target_peer.addr);
}
@@ -102,17 +102,17 @@ static void rpc_timeout_callback(evutil_socket_t fd, short events, void *arg)
struct swarmkv_rpc *swarmkv_rpc_launch(struct swarmkv_rpc_mgr *mgr, int thread_id, struct future *f)
{
- struct swarmkv_rpc_thr *thr=mgr->threads+thread_id;
- struct swarmkv_rpc *rpc=ALLOC(struct swarmkv_rpc, 1);
- rpc->sequence=__atomic_add_fetch(&mgr->seq_generator, 1, __ATOMIC_SEQ_CST);
+ struct swarmkv_rpc_thr *thr = mgr->threads + thread_id;
+ struct swarmkv_rpc *rpc = ALLOC(struct swarmkv_rpc, 1);
+ rpc->sequence = __atomic_add_fetch(&mgr->seq_generator, 1, __ATOMIC_SEQ_CST);
clock_gettime(CLOCK_REALTIME, &rpc->start);
- //struct timeval timeout={mgr->timeout_us/(1000*1000), mgr->timeout_us%(1000*1000)};
- rpc->timeout_ev=event_new(thr->evbase, -1, 0, rpc_timeout_callback, rpc);
+ // struct timeval timeout={mgr->timeout_us/(1000*1000), mgr->timeout_us%(1000*1000)};
+ rpc->timeout_ev = event_new(thr->evbase, -1, 0, rpc_timeout_callback, rpc);
event_priority_set(rpc->timeout_ev, 1);
event_add(rpc->timeout_ev, thr->common_timeout);
- rpc->thread_id=thread_id;
- rpc->ref_mgr=mgr;
- rpc->f=f;
+ rpc->thread_id = thread_id;
+ rpc->ref_mgr = mgr;
+ rpc->f = f;
HASH_ADD(hh, thr->rpc_table, sequence, sizeof(rpc->sequence), rpc);
return rpc;
}
@@ -127,38 +127,38 @@ void swarmkv_rpc_set_peer(struct swarmkv_rpc *rpc, const node_t *peer)
}
void swarmkv_rpc_set_timeout(struct swarmkv_rpc *rpc, long long timeout_us)
{
- struct timeval timeout={timeout_us/(1000*1000), timeout_us%(1000*1000)};
+ struct timeval timeout = {timeout_us / (1000 * 1000), timeout_us % (1000 * 1000)};
event_del(rpc->timeout_ev);
event_add(rpc->timeout_ev, &timeout);
return;
}
long long swarmkv_rpc_complete(struct swarmkv_rpc_mgr *mgr, int thread_id, long long sequence, void *reply)
{
- struct swarmkv_rpc *rpc=NULL;
- long long latency=-1;
+ struct swarmkv_rpc *rpc = NULL;
+ long long latency = -1;
HASH_FIND(hh, mgr->threads[thread_id].rpc_table, &sequence, sizeof(sequence), rpc);
- if(rpc==NULL)
+ if (rpc == NULL)
{
mgr->unknown_sequence++;
return -1;
}
struct timespec end;
clock_gettime(CLOCK_REALTIME, &end);
- latency=timespec_diff_usec(&rpc->start, &end);
+ latency = timespec_diff_usec(&rpc->start, &end);
- struct promise *p=future_to_promise(rpc->f);
+ struct promise *p = future_to_promise(rpc->f);
promise_success(p, reply);
swarmkv_rpc_free(rpc);
return latency;
}
long long swarmkv_rpc_mgr_count(struct swarmkv_rpc_mgr *mgr, int thread_id)
{
- assert(thread_id>=0 && thread_id<mgr->nr_worker_threads);
+ assert(thread_id >= 0 && thread_id < mgr->nr_worker_threads);
return HASH_COUNT(mgr->threads[thread_id].rpc_table);
}
void swarmkv_rpc_mgr_info(struct swarmkv_rpc_mgr *mgr, struct swarmkv_rpc_mgr_info *info)
{
- info->timed_out_rpcs=mgr->timed_out_rpcs;
- info->unknown_sequence=mgr->unknown_sequence;
+ info->timed_out_rpcs = mgr->timed_out_rpcs;
+ info->unknown_sequence = mgr->unknown_sequence;
return;
} \ No newline at end of file
diff --git a/src/swarmkv_store.c b/src/swarmkv_store.c
index 96d51c8..8d0d563 100644
--- a/src/swarmkv_store.c
+++ b/src/swarmkv_store.c
@@ -15,16 +15,16 @@
#include <unistd.h>
#include <string.h>
#include <pthread.h>
-#include <sys/time.h>//timercmp
+#include <sys/time.h> //timercmp
struct swarmkv_obj_specs
{
enum sobj_type type;
const char *type_name;
- void (*obj_free) (void *obj);
- void (*obj_serialize) (const void *obj, char **blob, size_t *blob_sz);
- void (*obj_merge_blob) (void *obj, const char *blob, size_t blob_sz);
- void *(*obj_replicate) (uuid_t uuid, const char *blob, size_t blob_sz);
+ void (*obj_free)(void *obj);
+ void (*obj_serialize)(const void *obj, char **blob, size_t *blob_sz);
+ void (*obj_merge_blob)(void *obj, const char *blob, size_t blob_sz);
+ void *(*obj_replicate)(uuid_t uuid, const char *blob, size_t blob_sz);
size_t (*obj_size)(const void *obj);
};
size_t undefined_obj_mem_size(void *obj)
@@ -33,112 +33,93 @@ size_t undefined_obj_mem_size(void *obj)
}
void undefined_obj_free(void *obj)
{
- assert(obj==NULL);
+ assert(obj == NULL);
return;
}
-struct swarmkv_obj_specs sobj_specs[__SWARMKV_OBJ_TYPE_MAX] =
-{
- {
- .type=OBJ_TYPE_STRING,
- .type_name="string",
- .obj_free=(void (*)(void *))LWW_register_free,
- .obj_serialize=(void (*)(const void *, char **, size_t *))LWW_register_serialize,
- .obj_merge_blob=(void (*)(void *, const char *, size_t))LWW_register_merge_blob,
- .obj_replicate=(void * (*)(uuid_t, const char *, size_t))LWW_register_replicate,
- .obj_size=(size_t (*)(const void *))LWW_register_mem_size
- },
- {
- .type=OBJ_TYPE_INTEGER,
- .type_name="integer",
- .obj_free=(void (*)(void *))PN_counter_free,
- .obj_serialize=(void (*)(const void *, char **, size_t *))PN_counter_serialize,
- .obj_merge_blob=(void (*)(void *, const char *, size_t))PN_counter_merge_blob,
- .obj_replicate=(void * (*)(uuid_t, const char *, size_t))PN_counter_replicate,
- .obj_size=(size_t (*)(const void *))PN_counter_mem_size
- },
- {
- .type=OBJ_TYPE_SET,
- .type_name="set",
- .obj_free=(void (*)(void *))OR_set_free,
- .obj_serialize=(void (*)(const void *, char **, size_t *))OR_set_serialize,
- .obj_merge_blob=(void (*)(void *, const char *, size_t))OR_set_merge_blob,
- .obj_replicate=(void * (*)(uuid_t, const char *, size_t))OR_set_replicate,
- .obj_size=(size_t (*)(const void *))OR_set_mem_size
- },
- {
- .type=OBJ_TYPE_HASH,
- .type_name="hash",
- .obj_free=(void (*)(void *))OR_map_free,
- .obj_serialize=(void (*)(const void *, char **, size_t *))OR_map_serialize,
- .obj_merge_blob=(void (*)(void *, const char *, size_t))OR_map_merge_blob,
- .obj_replicate=(void * (*)(uuid_t, const char *, size_t))OR_map_replicate,
- .obj_size=(size_t (*)(const void *))OR_map_mem_size
- },
- {
- .type=OBJ_TYPE_TOKEN_BUCKET,
- .type_name="token-bucket",
- .obj_free=(void (*)(void *))OC_token_bucket_free,
- .obj_serialize=(void (*)(const void *, char **, size_t *))OC_token_bucket_serialize,
- .obj_merge_blob=(void (*)(void *, const char *, size_t))OC_token_bucket_merge_blob,
- .obj_replicate=(void * (*)(uuid_t, const char *, size_t))OC_token_bucket_replicate,
- .obj_size=(size_t (*)(const void *))OC_token_bucket_mem_size,
- },
- {
- .type=OBJ_TYPE_FAIR_TOKEN_BUCKET,
- .type_name="fair-token-bucket",
- .obj_free=(void (*)(void *))fair_token_bucket_free,
- .obj_serialize=(void (*)(const void *, char **, size_t *))fair_token_bucket_serialize,
- .obj_merge_blob=(void (*)(void *, const char *, size_t))fair_token_bucket_merge_blob,
- .obj_replicate=(void * (*)(uuid_t, const char *, size_t))fair_token_bucket_replicate,
- .obj_size=(size_t (*)(const void *))fair_token_bucket_mem_size,
- },
- {
- .type=OBJ_TYPE_BULK_TOKEN_BUCKET,
- .type_name="bulk-token-bucket",
- .obj_free=(void (*)(void *))bulk_token_bucket_free,
- .obj_serialize=(void (*)(const void *, char **, size_t *))bulk_token_bucket_serialize,
- .obj_merge_blob=(void (*)(void *, const char *, size_t))bulk_token_bucket_merge_blob,
- .obj_replicate=(void * (*)(uuid_t, const char *, size_t))bulk_token_bucket_replicate,
- .obj_size=(size_t (*)(const void *))bulk_token_bucket_mem_size
- },
- {
- .type=OBJ_TYPE_BLOOM_FILTER,
- .type_name="bloom-filter",
- .obj_free=(void (*)(void *))AP_bloom_free,
- .obj_serialize=(void (*)(const void *, char **, size_t *))AP_bloom_serialize,
- .obj_merge_blob=(void (*)(void *, const char *, size_t))AP_bloom_merge_blob,
- .obj_replicate=(void * (*)(uuid_t, const char *, size_t))AP_bloom_replicate,
- .obj_size=(size_t (*)(const void *))AP_bloom_mem_size
- },
+struct swarmkv_obj_specs sobj_specs[__SWARMKV_OBJ_TYPE_MAX] =
{
- .type=OBJ_TYPE_CMS,
- .type_name="count-min-sketch",
- .obj_free=(void (*)(void *))CM_sketch_free,
- .obj_serialize=(void (*)(const void *, char **, size_t *))CM_sketch_serialize,
- .obj_merge_blob=(void (*)(void *, const char *, size_t))CM_sketch_merge_blob,
- .obj_replicate=(void * (*)(uuid_t, const char *, size_t))CM_sketch_replicate,
- .obj_size=(size_t (*)(const void *))CM_sketch_size
- },
- {
- .type=OBJ_TYPE_HYPERLOGLOG,
- .type_name="hyperloglog",
- .obj_free=(void (*)(void *))ST_hyperloglog_free,
- .obj_serialize=(void (*)(const void *, char **, size_t *))ST_hyperloglog_serialize,
- .obj_merge_blob=(void (*)(void *, const char *, size_t))ST_hyperloglog_merge_blob,
- .obj_replicate=(void * (*)(uuid_t, const char *, size_t))ST_hyperloglog_replicate,
- .obj_size=(size_t (*)(const void *))ST_hyperloglog_mem_size
- },
- {
- .type=OBJ_TYPE_UNDEFINED,
- .type_name="undefined",
- .obj_free=undefined_obj_free,
- .obj_serialize=NULL,
- .obj_merge_blob=NULL,
- .obj_replicate=NULL,
- .obj_size=(size_t (*)(const void *))undefined_obj_mem_size
- }
-};
-#define MODULE_SWAMRKV_STORE module_name_str("swarmkv.store")
+ {.type = OBJ_TYPE_STRING,
+ .type_name = "string",
+ .obj_free = (void (*)(void *))LWW_register_free,
+ .obj_serialize = (void (*)(const void *, char **, size_t *))LWW_register_serialize,
+ .obj_merge_blob = (void (*)(void *, const char *, size_t))LWW_register_merge_blob,
+ .obj_replicate = (void *(*)(uuid_t, const char *, size_t))LWW_register_replicate,
+ .obj_size = (size_t(*)(const void *))LWW_register_mem_size},
+ {.type = OBJ_TYPE_INTEGER,
+ .type_name = "integer",
+ .obj_free = (void (*)(void *))PN_counter_free,
+ .obj_serialize = (void (*)(const void *, char **, size_t *))PN_counter_serialize,
+ .obj_merge_blob = (void (*)(void *, const char *, size_t))PN_counter_merge_blob,
+ .obj_replicate = (void *(*)(uuid_t, const char *, size_t))PN_counter_replicate,
+ .obj_size = (size_t(*)(const void *))PN_counter_mem_size},
+ {.type = OBJ_TYPE_SET,
+ .type_name = "set",
+ .obj_free = (void (*)(void *))OR_set_free,
+ .obj_serialize = (void (*)(const void *, char **, size_t *))OR_set_serialize,
+ .obj_merge_blob = (void (*)(void *, const char *, size_t))OR_set_merge_blob,
+ .obj_replicate = (void *(*)(uuid_t, const char *, size_t))OR_set_replicate,
+ .obj_size = (size_t(*)(const void *))OR_set_mem_size},
+ {.type = OBJ_TYPE_HASH,
+ .type_name = "hash",
+ .obj_free = (void (*)(void *))OR_map_free,
+ .obj_serialize = (void (*)(const void *, char **, size_t *))OR_map_serialize,
+ .obj_merge_blob = (void (*)(void *, const char *, size_t))OR_map_merge_blob,
+ .obj_replicate = (void *(*)(uuid_t, const char *, size_t))OR_map_replicate,
+ .obj_size = (size_t(*)(const void *))OR_map_mem_size},
+ {
+ .type = OBJ_TYPE_TOKEN_BUCKET,
+ .type_name = "token-bucket",
+ .obj_free = (void (*)(void *))OC_token_bucket_free,
+ .obj_serialize = (void (*)(const void *, char **, size_t *))OC_token_bucket_serialize,
+ .obj_merge_blob = (void (*)(void *, const char *, size_t))OC_token_bucket_merge_blob,
+ .obj_replicate = (void *(*)(uuid_t, const char *, size_t))OC_token_bucket_replicate,
+ .obj_size = (size_t(*)(const void *))OC_token_bucket_mem_size,
+ },
+ {
+ .type = OBJ_TYPE_FAIR_TOKEN_BUCKET,
+ .type_name = "fair-token-bucket",
+ .obj_free = (void (*)(void *))fair_token_bucket_free,
+ .obj_serialize = (void (*)(const void *, char **, size_t *))fair_token_bucket_serialize,
+ .obj_merge_blob = (void (*)(void *, const char *, size_t))fair_token_bucket_merge_blob,
+ .obj_replicate = (void *(*)(uuid_t, const char *, size_t))fair_token_bucket_replicate,
+ .obj_size = (size_t(*)(const void *))fair_token_bucket_mem_size,
+ },
+ {.type = OBJ_TYPE_BULK_TOKEN_BUCKET,
+ .type_name = "bulk-token-bucket",
+ .obj_free = (void (*)(void *))bulk_token_bucket_free,
+ .obj_serialize = (void (*)(const void *, char **, size_t *))bulk_token_bucket_serialize,
+ .obj_merge_blob = (void (*)(void *, const char *, size_t))bulk_token_bucket_merge_blob,
+ .obj_replicate = (void *(*)(uuid_t, const char *, size_t))bulk_token_bucket_replicate,
+ .obj_size = (size_t(*)(const void *))bulk_token_bucket_mem_size},
+ {.type = OBJ_TYPE_BLOOM_FILTER,
+ .type_name = "bloom-filter",
+ .obj_free = (void (*)(void *))AP_bloom_free,
+ .obj_serialize = (void (*)(const void *, char **, size_t *))AP_bloom_serialize,
+ .obj_merge_blob = (void (*)(void *, const char *, size_t))AP_bloom_merge_blob,
+ .obj_replicate = (void *(*)(uuid_t, const char *, size_t))AP_bloom_replicate,
+ .obj_size = (size_t(*)(const void *))AP_bloom_mem_size},
+ {.type = OBJ_TYPE_CMS,
+ .type_name = "count-min-sketch",
+ .obj_free = (void (*)(void *))CM_sketch_free,
+ .obj_serialize = (void (*)(const void *, char **, size_t *))CM_sketch_serialize,
+ .obj_merge_blob = (void (*)(void *, const char *, size_t))CM_sketch_merge_blob,
+ .obj_replicate = (void *(*)(uuid_t, const char *, size_t))CM_sketch_replicate,
+ .obj_size = (size_t(*)(const void *))CM_sketch_size},
+ {.type = OBJ_TYPE_HYPERLOGLOG,
+ .type_name = "hyperloglog",
+ .obj_free = (void (*)(void *))ST_hyperloglog_free,
+ .obj_serialize = (void (*)(const void *, char **, size_t *))ST_hyperloglog_serialize,
+ .obj_merge_blob = (void (*)(void *, const char *, size_t))ST_hyperloglog_merge_blob,
+ .obj_replicate = (void *(*)(uuid_t, const char *, size_t))ST_hyperloglog_replicate,
+ .obj_size = (size_t(*)(const void *))ST_hyperloglog_mem_size},
+ {.type = OBJ_TYPE_UNDEFINED,
+ .type_name = "undefined",
+ .obj_free = undefined_obj_free,
+ .obj_serialize = NULL,
+ .obj_merge_blob = NULL,
+ .obj_replicate = NULL,
+ .obj_size = (size_t(*)(const void *))undefined_obj_mem_size}};
+#define MODULE_SWAMRKV_STORE module_name_str("swarmkv.store")
struct swarmkv_store_thread
{
@@ -163,23 +144,22 @@ struct swarmkv_store
const struct swarmkv_options *opts;
};
-
UT_icd ut_node_addr_icd = {sizeof(node_t), NULL, NULL, NULL};
struct swarmkv_store *module2store(struct swarmkv_module *module)
{
- assert(0==strcmp(module->name, "store"));
- struct swarmkv_store *store=container_of(module, struct swarmkv_store, module);
- assert(store==module->mod_ctx);
+ assert(0 == strcmp(module->name, "store"));
+ struct swarmkv_store *store = container_of(module, struct swarmkv_store, module);
+ assert(store == module->mod_ctx);
return store;
}
int __store_gettid(sds key, int nr_worker_threads)
{
- int shard_idx=key_hash_slot(key, sdslen(key))%nr_worker_threads;
+ int shard_idx = key_hash_slot(key, sdslen(key)) % nr_worker_threads;
return shard_idx;
}
-int store_gettid(struct swarmkv_module * mod_store, sds key)
+int store_gettid(struct swarmkv_module *mod_store, sds key)
{
return __store_gettid(key, module2store(mod_store)->opts->nr_worker_threads);
}
@@ -187,22 +167,22 @@ struct scontainer
{
struct sobj obj;
struct timeval op_timestamp;
- char is_pending; //waiting for reply 0f CRDT GET.
+ char is_pending; // waiting for reply 0f CRDT GET.
char is_in_table;
char is_in_sync_q;
int tid;
- UT_array *replica_node_list; //used by value owner for cache synchronization
+ UT_array *replica_node_list; // used by value owner for cache synchronization
UT_hash_handle hh;
- struct scontainer *prev; //hook to sync queue
- struct scontainer *next; //hook to sync queue
+ struct scontainer *prev; // hook to sync queue
+ struct scontainer *next; // hook to sync queue
};
static struct scontainer *scontainer_new(enum sobj_type type, const sds key, int tid)
{
- struct scontainer *ctr=ALLOC(struct scontainer, 1);
- ctr->obj.type=type;
- ctr->obj.key=sdsdup(key);
- ctr->tid=tid;
+ struct scontainer *ctr = ALLOC(struct scontainer, 1);
+ ctr->obj.type = type;
+ ctr->obj.key = sdsdup(key);
+ ctr->tid = tid;
gettimeofday(&ctr->op_timestamp, NULL);
return ctr;
}
@@ -210,12 +190,12 @@ static struct scontainer *scontainer_new(enum sobj_type type, const sds key, int
static void scontainer_free(struct scontainer *ctr)
{
assert(!ctr->is_in_table);
- if(ctr->replica_node_list)
+ if (ctr->replica_node_list)
{
utarray_free(ctr->replica_node_list);
- ctr->replica_node_list=NULL;
+ ctr->replica_node_list = NULL;
}
- assert(ctr->obj.type<__SWARMKV_OBJ_TYPE_MAX);
+ assert(ctr->obj.type < __SWARMKV_OBJ_TYPE_MAX);
sobj_specs[ctr->obj.type].obj_free(ctr->obj.raw);
sdsfree(ctr->obj.key);
free(ctr);
@@ -224,37 +204,36 @@ static void scontainer_free(struct scontainer *ctr)
static struct scontainer *scontainer_find(struct scontainer **table, const sds key)
{
- struct scontainer *ctr=NULL;
+ struct scontainer *ctr = NULL;
HASH_FIND(hh, *table, key, sdslen(key), ctr);
return ctr;
}
static void scontainer_join(struct scontainer **table, struct scontainer *ctr)
{
HASH_ADD_KEYPTR(hh, *table, ctr->obj.key, sdslen(ctr->obj.key), ctr);
- ctr->is_in_table=1;
- return;
+ ctr->is_in_table = 1;
+ return;
}
static void scontainer_remove(struct scontainer **table, struct scontainer *ctr)
{
HASH_DELETE(hh, *table, ctr);
- ctr->is_in_table=0;
+ ctr->is_in_table = 0;
return;
}
-
static int node_cmp(const void *a, const void *b)
{
- return node_compare((node_t *) a, (node_t *) b);
+ return node_compare((node_t *)a, (node_t *)b);
}
static int scontainer_add_replica_node(struct scontainer *ctr, const node_t *node)
{
- node_t *found=NULL;
- if(!ctr->replica_node_list)
+ node_t *found = NULL;
+ if (!ctr->replica_node_list)
{
utarray_new(ctr->replica_node_list, &ut_node_addr_icd);
}
- found=(node_t*)utarray_find(ctr->replica_node_list, node, node_cmp);
- if(found)
+ found = (node_t *)utarray_find(ctr->replica_node_list, node, node_cmp);
+ if (found)
{
return 0;
}
@@ -264,36 +243,38 @@ static int scontainer_add_replica_node(struct scontainer *ctr, const node_t *nod
}
static void scontainer_remove_replica_node(struct scontainer *ctr, const node_t *node)
{
- node_t *found=NULL;
- if(!ctr->replica_node_list) return;
- found=(node_t*)utarray_find(ctr->replica_node_list, node, node_cmp);
- if(!found) return;
- int pos=utarray_eltidx(ctr->replica_node_list, found);
+ node_t *found = NULL;
+ if (!ctr->replica_node_list)
+ return;
+ found = (node_t *)utarray_find(ctr->replica_node_list, node, node_cmp);
+ if (!found)
+ return;
+ int pos = utarray_eltidx(ctr->replica_node_list, found);
utarray_erase(ctr->replica_node_list, pos, 1);
return;
}
void store_add_scontainer(struct swarmkv_store *store, struct scontainer *ctr)
{
scontainer_join(&(store->threads[ctr->tid].obj_table), ctr);
- return;
+ return;
}
void store_remove_scontainer(struct swarmkv_store *store, struct scontainer *ctr)
{
- HASH_DELETE(hh, store->threads[ctr->tid].obj_table, ctr);
- ctr->is_in_table=0;
- if(ctr->is_in_sync_q)
+ HASH_DELETE(hh, store->threads[ctr->tid].obj_table, ctr);
+ ctr->is_in_table = 0;
+ if (ctr->is_in_sync_q)
{
DL_DELETE(store->threads[ctr->tid].sync_queue, ctr);
- ctr->is_in_sync_q=0;
+ ctr->is_in_sync_q = 0;
}
}
-typedef void sobj_callback_func_t(struct sobj * obj, void *cb_arg);
+typedef void sobj_callback_func_t(struct sobj *obj, void *cb_arg);
void store_iterate_sobj(struct swarmkv_store *store, int tid, sobj_callback_func_t *cb, void *cb_arg)
{
- struct scontainer *ctr=NULL, *tmp=NULL;
+ struct scontainer *ctr = NULL, *tmp = NULL;
HASH_ITER(hh, store->threads[tid].obj_table, ctr, tmp)
{
- if(!ctr->is_pending)
+ if (!ctr->is_pending)
{
cb(&ctr->obj, cb_arg);
}
@@ -301,12 +282,12 @@ void store_iterate_sobj(struct swarmkv_store *store, int tid, sobj_callback_func
}
struct scontainer *store_lookup_scontainer(struct swarmkv_store *store, sds key)
{
- struct scontainer *ctr=NULL;
- int designated_tid=key2tid(key, store->opts->nr_worker_threads);
- int real_tid=swarmkv_gettid(store->exec_cmd_handle);
- assert(designated_tid==real_tid);
- ctr=scontainer_find(&(store->threads[designated_tid].obj_table), key);
- if(0==pthread_mutex_trylock(&store->threads[designated_tid].sanity_lock))
+ struct scontainer *ctr = NULL;
+ int designated_tid = key2tid(key, store->opts->nr_worker_threads);
+ int real_tid = swarmkv_gettid(store->exec_cmd_handle);
+ assert(designated_tid == real_tid);
+ ctr = scontainer_find(&(store->threads[designated_tid].obj_table), key);
+ if (0 == pthread_mutex_trylock(&store->threads[designated_tid].sanity_lock))
{
pthread_mutex_unlock(&store->threads[designated_tid].sanity_lock);
}
@@ -314,7 +295,7 @@ struct scontainer *store_lookup_scontainer(struct swarmkv_store *store, sds key)
{
assert(0);
}
- if(ctr)
+ if (ctr)
{
return ctr;
}
@@ -325,10 +306,10 @@ struct scontainer *store_lookup_scontainer(struct swarmkv_store *store, sds key)
}
struct sobj *store_lookup(struct swarmkv_module *mod_store, sds key)
{
- struct swarmkv_store *store=module2store(mod_store);
- struct scontainer *ctr=NULL;
- ctr=store_lookup_scontainer(store, key);
- if(ctr) //&& !ctr->is_pending
+ struct swarmkv_store *store = module2store(mod_store);
+ struct scontainer *ctr = NULL;
+ ctr = store_lookup_scontainer(store, key);
+ if (ctr) //&& !ctr->is_pending
{
return &(ctr->obj);
}
@@ -337,79 +318,80 @@ struct sobj *store_lookup(struct swarmkv_module *mod_store, sds key)
return NULL;
}
}
-void store_get_uuid(struct swarmkv_module* mod_store, uuid_t uuid)
+void store_get_uuid(struct swarmkv_module *mod_store, uuid_t uuid)
{
- struct swarmkv_store *store=module2store(mod_store);
+ struct swarmkv_store *store = module2store(mod_store);
uuid_copy(uuid, store->opts->bin_uuid);
return;
}
-void store_get_node_addr(struct swarmkv_module* mod_store, node_t *node)
+void store_get_node_addr(struct swarmkv_module *mod_store, node_t *node)
{
- struct swarmkv_store *store=module2store(mod_store);
+ struct swarmkv_store *store = module2store(mod_store);
node_copy(node, &store->self);
return;
}
void store_mark_object_as_modified(struct swarmkv_module *mod_store, struct sobj *obj)
{
- struct swarmkv_store *store=module2store(mod_store);
- struct scontainer *ctr=container_of(obj, struct scontainer, obj);
+ struct swarmkv_store *store = module2store(mod_store);
+ struct scontainer *ctr = container_of(obj, struct scontainer, obj);
gettimeofday(&ctr->op_timestamp, NULL);
- if(!ctr->is_in_sync_q && ctr->replica_node_list)
+ if (!ctr->is_in_sync_q && ctr->replica_node_list)
{
DL_APPEND(store->threads[ctr->tid].sync_queue, ctr);
- ctr->is_in_sync_q=1;
+ ctr->is_in_sync_q = 1;
}
return;
}
int sobj_get_random_replica(struct sobj *obj, node_t *out)
{
- struct scontainer *ctr=container_of(obj, struct scontainer, obj);
- if(!ctr->replica_node_list || 0==utarray_len(ctr->replica_node_list)) return 0;
- node_t *replica=(node_t*)utarray_eltptr(ctr->replica_node_list, 0);
+ struct scontainer *ctr = container_of(obj, struct scontainer, obj);
+ if (!ctr->replica_node_list || 0 == utarray_len(ctr->replica_node_list))
+ return 0;
+ node_t *replica = (node_t *)utarray_eltptr(ctr->replica_node_list, 0);
node_copy(out, replica);
return 1;
}
enum cmd_exec_result handle_undefined_object(struct sobj *obj, struct swarmkv_reply **reply)
{
- assert(obj->type==OBJ_TYPE_UNDEFINED);
+ assert(obj->type == OBJ_TYPE_UNDEFINED);
node_t replica;
- int ret=0;
- ret=sobj_get_random_replica(obj, &replica);
- if(ret)
+ int ret = 0;
+ ret = sobj_get_random_replica(obj, &replica);
+ if (ret)
{
- *reply=swarmkv_reply_new_node(&replica, 1);
+ *reply = swarmkv_reply_new_node(&replica, 1);
return REDIRECT;
}
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
void scontainer_serialize(struct scontainer *ctr, char **blob, size_t *blob_sz)
{
- char *value_blob=NULL;
- size_t value_blob_sz=0;
- struct sobj *obj=&ctr->obj;
+ char *value_blob = NULL;
+ size_t value_blob_sz = 0;
+ struct sobj *obj = &ctr->obj;
sobj_specs[obj->type].obj_serialize(obj->raw, &value_blob, &value_blob_sz);
- char *mpack_buff=NULL;
- size_t mpack_sz=0;
- mpack_sz=sizeof(obj->type)+sizeof(ctr->op_timestamp);
- mpack_sz+=sizeof(size_t)+value_blob_sz;
- mpack_buff=ALLOC(char, mpack_sz);
- size_t offset=0;
+ char *mpack_buff = NULL;
+ size_t mpack_sz = 0;
+ mpack_sz = sizeof(obj->type) + sizeof(ctr->op_timestamp);
+ mpack_sz += sizeof(size_t) + value_blob_sz;
+ mpack_buff = ALLOC(char, mpack_sz);
+ size_t offset = 0;
memcpy(mpack_buff, &obj->type, sizeof(obj->type));
- offset+=sizeof(obj->type);
- memcpy(mpack_buff+offset, &ctr->op_timestamp, sizeof(ctr->op_timestamp));
- offset+=sizeof(ctr->op_timestamp);
+ offset += sizeof(obj->type);
+ memcpy(mpack_buff + offset, &ctr->op_timestamp, sizeof(ctr->op_timestamp));
+ offset += sizeof(ctr->op_timestamp);
- //We can add replica node list to the blob, but the merge process will consume more CPU time.
+ // We can add replica node list to the blob, but the merge process will consume more CPU time.
- memcpy(mpack_buff+offset, &value_blob_sz, sizeof(size_t));
- offset+=sizeof(size_t);
+ memcpy(mpack_buff + offset, &value_blob_sz, sizeof(size_t));
+ offset += sizeof(size_t);
- memcpy(mpack_buff+offset, value_blob, value_blob_sz);
- offset+=value_blob_sz;
- assert(offset==mpack_sz);
- *blob=mpack_buff;
- *blob_sz=mpack_sz;
+ memcpy(mpack_buff + offset, value_blob, value_blob_sz);
+ offset += value_blob_sz;
+ assert(offset == mpack_sz);
+ *blob = mpack_buff;
+ *blob_sz = mpack_sz;
free(value_blob);
return;
@@ -417,40 +399,39 @@ void scontainer_serialize(struct scontainer *ctr, char **blob, size_t *blob_sz)
void sobj_merge_blob(struct sobj *obj, const char *blob, size_t blob_sz, uuid_t uuid)
{
- struct scontainer *ctr=container_of(obj, struct scontainer, obj);
+ struct scontainer *ctr = container_of(obj, struct scontainer, obj);
struct timeval now;
enum sobj_type type;
- size_t offset=0;
- memcpy(&type, blob+offset, sizeof(type));
- offset+=sizeof(type);
- assert(ctr->obj.type==type || ctr->obj.type==OBJ_TYPE_UNDEFINED);
- ctr->obj.type=type;
+ size_t offset = 0;
+ memcpy(&type, blob + offset, sizeof(type));
+ offset += sizeof(type);
+ assert(ctr->obj.type == type || ctr->obj.type == OBJ_TYPE_UNDEFINED);
+ ctr->obj.type = type;
- memcpy(&ctr->op_timestamp, blob+offset, sizeof(ctr->op_timestamp));
- offset+=sizeof(ctr->op_timestamp);
+ memcpy(&ctr->op_timestamp, blob + offset, sizeof(ctr->op_timestamp));
+ offset += sizeof(ctr->op_timestamp);
gettimeofday(&now, NULL);
- if(timercmp(&ctr->op_timestamp, &now, >))
+ if (timercmp(&ctr->op_timestamp, &now, >))
{
fprintf(stderr, "Key %s is merging a blob which has a operation time in the future!\n", obj->key);
}
- size_t value_blob_sz=0;
- memcpy(&value_blob_sz, blob+offset, sizeof(size_t));
- offset+=sizeof(size_t);
- assert(offset+value_blob_sz==blob_sz);
- const char *value_blob=blob+offset;
- if(obj->raw == NULL)
+ size_t value_blob_sz = 0;
+ memcpy(&value_blob_sz, blob + offset, sizeof(size_t));
+ offset += sizeof(size_t);
+ assert(offset + value_blob_sz == blob_sz);
+ const char *value_blob = blob + offset;
+ if (obj->raw == NULL)
{
- obj->raw=sobj_specs[obj->type].obj_replicate(uuid, value_blob, value_blob_sz);
+ obj->raw = sobj_specs[obj->type].obj_replicate(uuid, value_blob, value_blob_sz);
}
else
{
sobj_specs[obj->type].obj_merge_blob(obj->raw, value_blob, value_blob_sz);
}
return;
-
}
enum CRDT_OP
@@ -467,15 +448,16 @@ struct crdt_generic_ctx
sds key;
};
void crdt_generic_ctx_free(struct crdt_generic_ctx *ctx)
-{
+{
sdsfree(ctx->key);
- ctx->store=NULL;
+ ctx->store = NULL;
free(ctx);
}
-__attribute__ ((unused)) static void store_remove_failed_peer(struct swarmkv_store *store, int tid, const node_t *peer)
+__attribute__((unused)) static void store_remove_failed_peer(struct swarmkv_store *store, int tid, const node_t *peer)
{
- struct scontainer *ctr=NULL, *tmp=NULL;
- if(tid>=store->opts->nr_worker_threads) return;//swarmkv_close() is called.
+ struct scontainer *ctr = NULL, *tmp = NULL;
+ if (tid >= store->opts->nr_worker_threads)
+ return; // swarmkv_close() is called.
HASH_ITER(hh, store->threads[tid].obj_table, ctr, tmp)
{
scontainer_remove_replica_node(ctr, peer);
@@ -484,199 +466,201 @@ __attribute__ ((unused)) static void store_remove_failed_peer(struct swarmkv_sto
}
static void crdt_generic_on_reply(const struct swarmkv_reply *reply, void *user)
{
- struct crdt_generic_ctx *ctx=(struct crdt_generic_ctx *)user;
-
+ struct crdt_generic_ctx *ctx = (struct crdt_generic_ctx *)user;
+
uuid_t uuid;
store_get_uuid(&(ctx->store->module), uuid);
-
- __attribute__ ((unused)) long long error_before=ctx->store->sync_err;
- switch(ctx->op)
+ __attribute__((unused)) long long error_before = ctx->store->sync_err;
+
+ switch (ctx->op)
+ {
+ case CRDT_GET:
{
- case CRDT_GET:
+ struct scontainer *ctr = NULL;
+ ctr = store_lookup_scontainer(ctx->store, ctx->key);
+ if (ctr && reply->type == SWARMKV_REPLY_VERBATIM)
{
- struct scontainer *ctr=NULL;
- ctr=store_lookup_scontainer(ctx->store, ctx->key);
- if(ctr && reply->type==SWARMKV_REPLY_VERBATIM)
- {
- sobj_merge_blob(&ctr->obj, reply->str, reply->len, uuid);
- ctr->is_pending=0;
- atomic_inc(&ctx->store->sync_ok);
- }
- else
- {
- atomic_inc(&ctx->store->sync_err);
- }
- break;
+ sobj_merge_blob(&ctr->obj, reply->str, reply->len, uuid);
+ ctr->is_pending = 0;
+ atomic_inc(&ctx->store->sync_ok);
}
- case CRDT_MERGE:
+ else
{
- if(reply->type==SWARMKV_REPLY_INTEGER && reply->integer>0)
- {
- atomic_add(&ctx->store->sync_ok, reply->integer);
- }
- else
- {
- if(0 && reply->type==SWARMKV_REPLY_ERROR && strcasestr(reply->str, "timed out"))
- {
- struct scontainer *ctr=NULL;
- ctr=store_lookup_scontainer(ctx->store, ctx->key);
- scontainer_remove_replica_node(ctr, &ctx->peer);
- }
- atomic_inc(&ctx->store->sync_err);
- }
- break;
+ atomic_inc(&ctx->store->sync_err);
}
- case CRDT_MEET:
+ break;
+ }
+ case CRDT_MERGE:
+ {
+ if (reply->type == SWARMKV_REPLY_INTEGER && reply->integer > 0)
{
- if(reply->type==SWARMKV_REPLY_INTEGER)
- {
- atomic_inc(&ctx->store->sync_ok);
- }
- else
+ atomic_add(&ctx->store->sync_ok, reply->integer);
+ }
+ else
+ {
+ //In batch synchronization, the merge command operates multiple keys of one thread,
+ //the ctx->key is the first key of the batch.
+ if (reply->type == SWARMKV_REPLY_ERROR && strcasestr(reply->str, "timed out"))
{
- atomic_inc(&ctx->store->sync_err);
+ int tid = __store_gettid(ctx->key, ctx->store->opts->nr_worker_threads);
+ store_remove_failed_peer(ctx->store, tid, &ctx->peer);
}
- break;
+ atomic_inc(&ctx->store->sync_err);
}
- default:
+ break;
+ }
+ case CRDT_MEET:
+ {
+ if (reply->type == SWARMKV_REPLY_INTEGER)
+ {
+ atomic_inc(&ctx->store->sync_ok);
+ }
+ else
{
atomic_inc(&ctx->store->sync_err);
- break;
}
+ break;
+ }
+ default:
+ {
+ atomic_inc(&ctx->store->sync_err);
+ break;
}
- //assert(ctx->store->sync_err==error_before);
+ }
+ // assert(ctx->store->sync_err==error_before);
crdt_generic_ctx_free(ctx);
return;
}
void crdt_generic_call(struct swarmkv_store *store, enum CRDT_OP op, const node_t *peer, int argc, const char *argv[], size_t *argv_len)
{
- struct crdt_generic_ctx *ctx=NULL;
+ struct crdt_generic_ctx *ctx = NULL;
assert(peer);
- ctx=ALLOC(struct crdt_generic_ctx, 1);
- ctx->op=op;
- ctx->store=store;
- ctx->key=sdsnew(argv[2]);
+ ctx = ALLOC(struct crdt_generic_ctx, 1);
+ ctx->op = op;
+ ctx->store = store;
+ ctx->key = sdsnew(argv[2]);
node_copy(&ctx->peer, peer);
- swarmkv_async_command_on_argv(store->exec_cmd_handle, crdt_generic_on_reply, ctx, peer->addr, argc, argv, argv_len);
+ swarmkv_async_command_on_argv(store->exec_cmd_handle, crdt_generic_on_reply, ctx, peer->addr, argc, argv, argv_len);
return;
}
-#define MONITOR_SYNC_EVENT_NAME "crdt-sync-cycle"
-#define MAX_SYNC_PER_PERIOD 100000
+#define MONITOR_SYNC_EVENT_NAME "crdt-sync-cycle"
+#define MAX_SYNC_PER_PERIOD 100000
int store_batch_sync(struct swarmkv_store *store, int tid)
{
- int n_synced=0;
- struct swarmkv_store_thread *thr=&store->threads[tid];
- struct sync_master *sync_master=sync_master_new();
- struct scontainer *ctr=NULL, *tmp=NULL;
+ int n_synced = 0;
+ struct swarmkv_store_thread *thr = &store->threads[tid];
+ struct sync_master *sync_master = sync_master_new();
+ struct scontainer *ctr = NULL, *tmp = NULL;
DL_FOREACH_SAFE(thr->sync_queue, ctr, tmp)
{
- char *blob=NULL;
- size_t blob_sz=0;
+ char *blob = NULL;
+ size_t blob_sz = 0;
scontainer_serialize(ctr, &blob, &blob_sz);
- if(store->opts->batch_sync_enabled)
+ if (store->opts->batch_sync_enabled)
{
sync_master_add_obj(sync_master, ctr->obj.key, blob, blob_sz,
- utarray_front(ctr->replica_node_list), utarray_len(ctr->replica_node_list));
-
+ utarray_front(ctr->replica_node_list), utarray_len(ctr->replica_node_list));
}
else
{
const char *argv[4];
size_t argv_len[4];
- argv[0]="crdt";
- argv_len[0]=strlen(argv[0]);
- argv[1]="merge";
- argv_len[1]=strlen(argv[1]);
- argv[2]=ctr->obj.key;
- argv_len[2]=sdslen(ctr->obj.key);
- argv[3]=blob;
- argv_len[3]=blob_sz;
- for(int i=0; i<utarray_len(ctr->replica_node_list); i++)
+ argv[0] = "crdt";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = "merge";
+ argv_len[1] = strlen(argv[1]);
+ argv[2] = ctr->obj.key;
+ argv_len[2] = sdslen(ctr->obj.key);
+ argv[3] = blob;
+ argv_len[3] = blob_sz;
+ for (int i = 0; i < utarray_len(ctr->replica_node_list); i++)
{
- node_t *peer=utarray_eltptr(ctr->replica_node_list, i);
+ node_t *peer = utarray_eltptr(ctr->replica_node_list, i);
crdt_generic_call(store, CRDT_MERGE, peer, 4, argv, argv_len);
}
free(blob);
}
DL_DELETE(thr->sync_queue, ctr);
- ctr->is_in_sync_q=0;
+ ctr->is_in_sync_q = 0;
store->synced++;
n_synced++;
- if(n_synced>=MAX_SYNC_PER_PERIOD) break;
+ if (n_synced >= MAX_SYNC_PER_PERIOD)
+ break;
}
- struct sync_task *task=NULL;
- task=sync_master_get_task(sync_master);
- while(task)
+ struct sync_task *task = NULL;
+ task = sync_master_get_task(sync_master);
+ while (task)
{
- size_t n_data=sync_task_key_count(task);
- const char *argv[n_data*2+2];
- size_t argv_len[n_data*2+2];
- argv[0]="crdt";
- argv_len[0]=strlen(argv[0]);
- argv[1]="merge";
- argv_len[1]=strlen(argv[1]);
- sync_task_read_key_blob(task, argv+2, argv_len+2, n_data*2);
- crdt_generic_call(store, CRDT_MERGE, sync_task_peer(task), n_data*2+2, argv, argv_len);
+ size_t n_data = sync_task_key_count(task);
+ const char *argv[n_data * 2 + 2];
+ size_t argv_len[n_data * 2 + 2];
+ argv[0] = "crdt";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = "merge";
+ argv_len[1] = strlen(argv[1]);
+ sync_task_read_key_blob(task, argv + 2, argv_len + 2, n_data * 2);
+ crdt_generic_call(store, CRDT_MERGE, sync_task_peer(task), n_data * 2 + 2, argv, argv_len);
sync_task_free(task);
- task=sync_master_get_task(sync_master);
+ task = sync_master_get_task(sync_master);
}
sync_master_free(sync_master);
return n_synced;
}
-void swarmkv_store_periodic(struct swarmkv_module * mod_store, int thread_id)
+void swarmkv_store_periodic(struct swarmkv_module *mod_store, int thread_id)
{
- struct swarmkv_store *store=module2store(mod_store);
- struct scontainer *ctr=NULL, *tmp=NULL;
+ struct swarmkv_store *store = module2store(mod_store);
+ struct scontainer *ctr = NULL, *tmp = NULL;
struct timespec start, end;
- int n_synced=0;
- int real_tid=swarmkv_gettid(store->exec_cmd_handle);
- assert(real_tid==thread_id);
+ int n_synced = 0;
+ int real_tid = swarmkv_gettid(store->exec_cmd_handle);
+ assert(real_tid == thread_id);
clock_gettime(CLOCK_MONOTONIC, &start);
- struct swarmkv_store_thread *thr=&store->threads[real_tid];
+ struct swarmkv_store_thread *thr = &store->threads[real_tid];
thr->calls++;
- if(store->opts->batch_sync_enabled)
+ if (store->opts->batch_sync_enabled)
{
- n_synced=store_batch_sync(store, real_tid);
+ n_synced = store_batch_sync(store, real_tid);
}
else
{
DL_FOREACH_SAFE(thr->sync_queue, ctr, tmp)
{
- char *blob=NULL;
- size_t blob_sz=0;
+ char *blob = NULL;
+ size_t blob_sz = 0;
scontainer_serialize(ctr, &blob, &blob_sz);
const char *argv[4];
size_t argv_len[4];
- argv[0]="crdt";
- argv_len[0]=strlen(argv[0]);
- argv[1]="merge";
- argv_len[1]=strlen(argv[1]);
- argv[2]=ctr->obj.key;
- argv_len[2]=sdslen(ctr->obj.key);
- argv[3]=blob;
- argv_len[3]=blob_sz;
- for(int i=0; i<utarray_len(ctr->replica_node_list); i++)
+ argv[0] = "crdt";
+ argv_len[0] = strlen(argv[0]);
+ argv[1] = "merge";
+ argv_len[1] = strlen(argv[1]);
+ argv[2] = ctr->obj.key;
+ argv_len[2] = sdslen(ctr->obj.key);
+ argv[3] = blob;
+ argv_len[3] = blob_sz;
+ for (int i = 0; i < utarray_len(ctr->replica_node_list); i++)
{
- node_t *peer=utarray_eltptr(ctr->replica_node_list, i);
+ node_t *peer = utarray_eltptr(ctr->replica_node_list, i);
crdt_generic_call(store, CRDT_MERGE, peer, 4, argv, argv_len);
}
free(blob);
DL_DELETE(thr->sync_queue, ctr);
- ctr->is_in_sync_q=0;
+ ctr->is_in_sync_q = 0;
store->synced++;
n_synced++;
- if(n_synced>=MAX_SYNC_PER_PERIOD) break;
+ if (n_synced >= MAX_SYNC_PER_PERIOD)
+ break;
}
}
- thr->n_keys=HASH_COUNT(thr->obj_table);
+ thr->n_keys = HASH_COUNT(thr->obj_table);
DL_COUNT(thr->sync_queue, ctr, thr->keys_to_sync);
clock_gettime(CLOCK_MONOTONIC, &end);
- if(n_synced)
+ if (n_synced)
{
swarmkv_monitor_record_event(store->mod_monitor, MONITOR_SYNC_EVENT_NAME, timespec_diff_usec(&start, &end));
}
@@ -684,11 +668,11 @@ void swarmkv_store_periodic(struct swarmkv_module * mod_store, int thread_id)
struct swarmkv_module *swarmkv_store_new(const struct swarmkv_options *opts)
{
- struct swarmkv_store *store=ALLOC(struct swarmkv_store, 1);
+ struct swarmkv_store *store = ALLOC(struct swarmkv_store, 1);
strncpy(store->module.name, "store", sizeof(store->module.name));
- store->module.mod_ctx=store;
- store->opts=opts;
- store->threads=ALLOC(struct swarmkv_store_thread, opts->nr_worker_threads);
+ store->module.mod_ctx = store;
+ store->opts = opts;
+ store->threads = ALLOC(struct swarmkv_store_thread, opts->nr_worker_threads);
node_init(&store->self, opts->cluster_announce_ip, opts->cluster_announce_port);
@@ -696,52 +680,52 @@ struct swarmkv_module *swarmkv_store_new(const struct swarmkv_options *opts)
}
void swarmkv_store_set_exec_cmd_handle(struct swarmkv_module *mod_store, struct swarmkv *exec_cmd_handle)
{
- struct swarmkv_store *store=module2store(mod_store);
- store->exec_cmd_handle=exec_cmd_handle;
+ struct swarmkv_store *store = module2store(mod_store);
+ store->exec_cmd_handle = exec_cmd_handle;
return;
}
void swarmkv_store_free(struct swarmkv_module *mod_store)
{
- struct swarmkv_store *store=module2store(mod_store);
- struct scontainer *ctr=NULL, *tmp=NULL;
-
- for(size_t i=0; i<store->opts->nr_worker_threads; i++)
+ struct swarmkv_store *store = module2store(mod_store);
+ struct scontainer *ctr = NULL, *tmp = NULL;
+
+ for (size_t i = 0; i < store->opts->nr_worker_threads; i++)
{
HASH_ITER(hh, store->threads[i].obj_table, ctr, tmp)
{
- assert(ctr->tid==i);
+ assert(ctr->tid == i);
scontainer_remove(&(store->threads[i].obj_table), ctr);
scontainer_free(ctr);
}
}
free(store->threads);
- store->threads=NULL;
+ store->threads = NULL;
free(store);
return;
}
void swarmkv_store_set_monitor_handle(struct swarmkv_module *mod_store, struct swarmkv_module *mod_monitor)
{
- struct swarmkv_store *store=module2store(mod_store);
- store->mod_monitor=mod_monitor;
+ struct swarmkv_store *store = module2store(mod_store);
+ store->mod_monitor = mod_monitor;
swarmkv_monitor_register_event(mod_monitor, MONITOR_SYNC_EVENT_NAME);
}
void swarmkv_store_info(struct swarmkv_module *mod_store, struct store_info *info)
{
- struct swarmkv_store *store=module2store(mod_store);
- info->keys=0;
- info->keys_to_sync=0;
- struct swarmkv_store_thread *thread=NULL;
+ struct swarmkv_store *store = module2store(mod_store);
+ info->keys = 0;
+ info->keys_to_sync = 0;
+ struct swarmkv_store_thread *thread = NULL;
memset(info, 0, sizeof(struct store_info));
- for(size_t i=0; i<store->opts->nr_worker_threads; i++)
+ for (size_t i = 0; i < store->opts->nr_worker_threads; i++)
{
- thread = store->threads+i;
+ thread = store->threads + i;
info->keys_to_sync += __sync_add_and_fetch(&thread->keys_to_sync, 0);
info->keys += __sync_add_and_fetch(&thread->n_keys, 0);
}
- info->sync_ok=__sync_add_and_fetch(&store->sync_ok, 0);
- info->sync_err=__sync_add_and_fetch(&store->sync_err, 0);
- info->synced=store->synced;
+ info->sync_ok = __sync_add_and_fetch(&store->sync_ok, 0);
+ info->sync_err = __sync_add_and_fetch(&store->sync_err, 0);
+ info->synced = store->synced;
}
UT_icd ut_array_matched_reply = {sizeof(struct swarmkv_reply *), NULL, NULL, NULL};
@@ -749,316 +733,311 @@ UT_icd ut_array_matched_reply = {sizeof(struct swarmkv_reply *), NULL, NULL, NUL
struct pattern_match_arg
{
sds pattern;
- UT_array *matched_replies;
+ UT_array *matched_replies;
};
enum cmd_exec_result type_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*TYPE key*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ /*TYPE key*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
return NEED_KEY_ROUTE;
}
- *reply=swarmkv_reply_new_string_fmt(sobj_specs[obj->type].type_name);
+ *reply = swarmkv_reply_new_string_fmt(sobj_specs[obj->type].type_name);
return FINISHED;
}
enum cmd_exec_result crdt_add_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*CRDT ADD key [IP:port ...]*/
- struct scontainer *ctr=NULL;
- struct swarmkv_store *store=module2store(mod_store);
- size_t max_pull_node_num=4;
+ /*CRDT ADD key [IP:port ...]*/
+ struct scontainer *ctr = NULL;
+ struct swarmkv_store *store = module2store(mod_store);
+ size_t max_pull_node_num = 4;
- sds key=cmd->argv[2];
- int tid=store_gettid(mod_store, key);
- int real_tid=swarmkv_gettid(store->exec_cmd_handle);
- assert(tid==real_tid);
+ sds key = cmd->argv[2];
+ int tid = store_gettid(mod_store, key);
+ int real_tid = swarmkv_gettid(store->exec_cmd_handle);
+ assert(tid == real_tid);
+ size_t n_replica_node = cmd->argc - 3;
-
- size_t n_replica_node=cmd->argc-3;
-
- ctr=store_lookup_scontainer(store, key);
- if(!ctr)
+ ctr = store_lookup_scontainer(store, key);
+ if (!ctr)
{
- ctr=scontainer_new(OBJ_TYPE_UNDEFINED, key, tid);
- if(n_replica_node>0)//need crdt get from replicas
+ ctr = scontainer_new(OBJ_TYPE_UNDEFINED, key, tid);
+ if (n_replica_node > 0) // need crdt get from replicas
{
- ctr->is_pending=1;
+ ctr->is_pending = 1;
}
else
{
- ctr->is_pending=0;
+ ctr->is_pending = 0;
}
store_add_scontainer(store, ctr);
}
- node_t *replica_nodes=ALLOC(node_t, n_replica_node);
- for(size_t i=0; i<n_replica_node; i++)
+ node_t *replica_nodes = ALLOC(node_t, n_replica_node);
+ for (size_t i = 0; i < n_replica_node; i++)
{
- node_init_from_sds(&replica_nodes[i], cmd->argv[3+i]);
- assert(node_compare(replica_nodes+i, &store->self)!=0);
- scontainer_add_replica_node(ctr, replica_nodes+i);
+ node_init_from_sds(&replica_nodes[i], cmd->argv[3 + i]);
+ assert(node_compare(replica_nodes + i, &store->self) != 0);
+ scontainer_add_replica_node(ctr, replica_nodes + i);
}
const char *crdt_get_argv[3];
size_t crdt_get_argv_len[3];
- crdt_get_argv[0]="crdt";
- crdt_get_argv_len[0]=strlen(crdt_get_argv[0]);
- crdt_get_argv[1]="get";
- crdt_get_argv_len[1]=strlen(crdt_get_argv[1]);
- crdt_get_argv[2]=key;
- crdt_get_argv_len[2]=sdslen(key);
+ crdt_get_argv[0] = "crdt";
+ crdt_get_argv_len[0] = strlen(crdt_get_argv[0]);
+ crdt_get_argv[1] = "get";
+ crdt_get_argv_len[1] = strlen(crdt_get_argv[1]);
+ crdt_get_argv[2] = key;
+ crdt_get_argv_len[2] = sdslen(key);
const char *crdt_meet_argv[4];
size_t crdt_meet_argv_len[4];
- for(size_t i=0; i<n_replica_node; i++)
+ for (size_t i = 0; i < n_replica_node; i++)
{
- if(i<max_pull_node_num)
+ if (i < max_pull_node_num)
{
- crdt_generic_call(store, CRDT_GET, replica_nodes+i, 3, crdt_get_argv, crdt_get_argv_len);
+ crdt_generic_call(store, CRDT_GET, replica_nodes + i, 3, crdt_get_argv, crdt_get_argv_len);
}
- crdt_meet_argv[0]="crdt";
- crdt_meet_argv_len[0]=strlen(crdt_meet_argv[0]);
- crdt_meet_argv[1]="meet";
- crdt_meet_argv_len[1]=strlen(crdt_meet_argv[1]);
- crdt_meet_argv[2]=key;
- crdt_meet_argv_len[2]=sdslen(key);
- crdt_meet_argv[3]=node_addr2cstr(&store->self);
- crdt_meet_argv_len[3]=strlen(crdt_meet_argv[3]);
- crdt_generic_call(store, CRDT_MEET, replica_nodes+i, 4, crdt_meet_argv, crdt_meet_argv_len);
+ crdt_meet_argv[0] = "crdt";
+ crdt_meet_argv_len[0] = strlen(crdt_meet_argv[0]);
+ crdt_meet_argv[1] = "meet";
+ crdt_meet_argv_len[1] = strlen(crdt_meet_argv[1]);
+ crdt_meet_argv[2] = key;
+ crdt_meet_argv_len[2] = sdslen(key);
+ crdt_meet_argv[3] = node_addr2cstr(&store->self);
+ crdt_meet_argv_len[3] = strlen(crdt_meet_argv[3]);
+ crdt_generic_call(store, CRDT_MEET, replica_nodes + i, 4, crdt_meet_argv, crdt_meet_argv_len);
}
free(replica_nodes);
- *reply=swarmkv_reply_new_status("OK");
+ *reply = swarmkv_reply_new_status("OK");
return FINISHED;
}
enum cmd_exec_result crdt_get_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* CRDT GET key */
- struct swarmkv_store *store=module2store(mod_store);
- struct scontainer *ctr=NULL;
- const sds key=cmd->argv[2];
- char *blob=NULL;
- size_t blob_sz=0;
-
- ctr=store_lookup_scontainer(store, key);
- if(ctr)
+ /* CRDT GET key */
+ struct swarmkv_store *store = module2store(mod_store);
+ struct scontainer *ctr = NULL;
+ const sds key = cmd->argv[2];
+ char *blob = NULL;
+ size_t blob_sz = 0;
+
+ ctr = store_lookup_scontainer(store, key);
+ if (ctr)
{
- if(ctr->obj.type!=OBJ_TYPE_UNDEFINED)
+ if (ctr->obj.type != OBJ_TYPE_UNDEFINED)
{
scontainer_serialize(ctr, &blob, &blob_sz);
- *reply=swarmkv_reply_new_verbatim(blob, blob_sz, "crd");
+ *reply = swarmkv_reply_new_verbatim(blob, blob_sz, "crd");
free(blob);
}
else
{
- *reply=swarmkv_reply_new_nil();
+ *reply = swarmkv_reply_new_nil();
}
}
else
{
- *reply=swarmkv_reply_new_nil();
+ *reply = swarmkv_reply_new_nil();
}
return FINISHED;
-
}
enum cmd_exec_result crdt_merge_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* CRDT MERGE key blob [key blob ...]*/
- struct sobj *obj=NULL;
- sds key=NULL, blob=NULL;
- long long synced=0;
+ /* CRDT MERGE key blob [key blob ...]*/
+ struct sobj *obj = NULL;
+ sds key = NULL, blob = NULL;
+ long long synced = 0;
uuid_t uuid;
- int __attribute__((__unused__))first_key_tid=0;
- int __attribute__((__unused__))tid=0;
- first_key_tid=store_gettid(mod_store, cmd->argv[2]);
+ int __attribute__((__unused__)) first_key_tid = 0;
+ int __attribute__((__unused__)) tid = 0;
+ first_key_tid = store_gettid(mod_store, cmd->argv[2]);
node_t self;
store_get_node_addr(mod_store, &self);
store_get_uuid(mod_store, uuid);
- for(size_t i=0; i<cmd->argc-2; i+=2)
+ for (size_t i = 0; i < cmd->argc - 2; i += 2)
{
- key=cmd->argv[2+i];
- blob=cmd->argv[2+i+1];
- obj=store_lookup(mod_store, key);
- if(obj)
+ key = cmd->argv[2 + i];
+ blob = cmd->argv[2 + i + 1];
+ obj = store_lookup(mod_store, key);
+ if (obj)
{
sobj_merge_blob(obj, blob, sdslen(blob), uuid);
synced++;
}
- tid=store_gettid(mod_store, key);
- assert(tid==first_key_tid);
+ tid = store_gettid(mod_store, key);
+ assert(tid == first_key_tid);
}
- *reply=swarmkv_reply_new_integer(synced);
+ *reply = swarmkv_reply_new_integer(synced);
return FINISHED;
}
enum cmd_exec_result crdt_del_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- /* CRDT DEL <key> */
- sds key=cmd->argv[2];
- struct scontainer *ctr=NULL;
- struct swarmkv_store *store=module2store(mod_store);
- ctr=store_lookup_scontainer(store, key);
- if(ctr)
+ /* CRDT DEL <key> */
+ sds key = cmd->argv[2];
+ struct scontainer *ctr = NULL;
+ struct swarmkv_store *store = module2store(mod_store);
+ ctr = store_lookup_scontainer(store, key);
+ if (ctr)
{
store_remove_scontainer(store, ctr);
scontainer_free(ctr);
- *reply=swarmkv_reply_new_integer(1);
+ *reply = swarmkv_reply_new_integer(1);
}
else
{
- *reply=swarmkv_reply_new_integer(0);
- }
+ *reply = swarmkv_reply_new_integer(0);
+ }
return FINISHED;
}
enum cmd_exec_result crdt_meet_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
/* CRDT MEET <key> IP:port [IP:port ...]*/
- struct scontainer *ctr=NULL;
- const sds key=cmd->argv[2];
-
- node_t replica_node;
-
- struct swarmkv_store *store=module2store(mod_store);
- //assert(node_compare(&replica_node, &store->self)!=0);
- //printf("CRDT MEET %s %s <- %s\n", key, store->self.addr, cmd->argv[3]);
- ctr=store_lookup_scontainer(store, key);
- int added=0;
- if(ctr)
+ struct scontainer *ctr = NULL;
+ const sds key = cmd->argv[2];
+
+ node_t replica_node;
+
+ struct swarmkv_store *store = module2store(mod_store);
+ // assert(node_compare(&replica_node, &store->self)!=0);
+ // printf("CRDT MEET %s %s <- %s\n", key, store->self.addr, cmd->argv[3]);
+ ctr = store_lookup_scontainer(store, key);
+ int added = 0;
+ if (ctr)
{
- for(int i=0; i<cmd->argc-3; i++)
+ for (int i = 0; i < cmd->argc - 3; i++)
{
- node_init_from_sds(&replica_node, cmd->argv[3+i]);
- if(node_compare(&replica_node, &store->self)==0)
+ node_init_from_sds(&replica_node, cmd->argv[3 + i]);
+ if (node_compare(&replica_node, &store->self) == 0)
{
continue;
}
- added+=scontainer_add_replica_node(ctr, &replica_node);
+ added += scontainer_add_replica_node(ctr, &replica_node);
}
- *reply=swarmkv_reply_new_integer(added);
+ *reply = swarmkv_reply_new_integer(added);
}
else
{
- *reply=swarmkv_reply_new_nil();
+ *reply = swarmkv_reply_new_nil();
}
return FINISHED;
}
-static void pattern_match_function(struct sobj * obj, void *cb_arg)
+static void pattern_match_function(struct sobj *obj, void *cb_arg)
{
- int is_matched=0;
- struct pattern_match_arg *arg=(struct pattern_match_arg*)cb_arg;
- struct swarmkv_reply *r=NULL;
- is_matched=stringmatchlen(arg->pattern, sdslen(arg->pattern), obj->key, sdslen(obj->key), 0);
- if(is_matched)
+ int is_matched = 0;
+ struct pattern_match_arg *arg = (struct pattern_match_arg *)cb_arg;
+ struct swarmkv_reply *r = NULL;
+ is_matched = stringmatchlen(arg->pattern, sdslen(arg->pattern), obj->key, sdslen(obj->key), 0);
+ if (is_matched)
{
- r=swarmkv_reply_new_string(obj->key, sdslen(obj->key));
+ r = swarmkv_reply_new_string(obj->key, sdslen(obj->key));
utarray_push_back(arg->matched_replies, &r);
}
return;
}
-
enum cmd_exec_result crdt_keys_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-//CRDT KEYS tid pattern
- int i=0, n_matched=0;
+ // CRDT KEYS tid pattern
+ int i = 0, n_matched = 0;
struct pattern_match_arg cb_arg;
- int thread_id=atoll(cmd->argv[2]);
- cb_arg.pattern=cmd->argv[3];
- utarray_new(cb_arg.matched_replies, &ut_array_matched_reply);
- struct swarmkv_store *store=module2store(mod_store);
- if(thread_id>store->opts->nr_worker_threads)
+ int thread_id = atoll(cmd->argv[2]);
+ cb_arg.pattern = cmd->argv[3];
+ utarray_new(cb_arg.matched_replies, &ut_array_matched_reply);
+ struct swarmkv_store *store = module2store(mod_store);
+ if (thread_id > store->opts->nr_worker_threads)
{
- *reply=swarmkv_reply_new_error("Invalid thread id");
+ *reply = swarmkv_reply_new_error("Invalid thread id");
return FINISHED;
}
- store_iterate_sobj(store, thread_id, pattern_match_function, &cb_arg);
- n_matched=utarray_len(cb_arg.matched_replies);
- if(n_matched>0)
+ store_iterate_sobj(store, thread_id, pattern_match_function, &cb_arg);
+ n_matched = utarray_len(cb_arg.matched_replies);
+ if (n_matched > 0)
{
- *reply=swarmkv_reply_new_array(n_matched);
- for(i=0; i<n_matched; i++)
+ *reply = swarmkv_reply_new_array(n_matched);
+ for (i = 0; i < n_matched; i++)
{
- (*reply)->elements[i]=*(struct swarmkv_reply **)utarray_eltptr(cb_arg.matched_replies, i);
+ (*reply)->elements[i] = *(struct swarmkv_reply **)utarray_eltptr(cb_arg.matched_replies, i);
}
}
else
{
- *reply=swarmkv_reply_new_nil();
+ *reply = swarmkv_reply_new_nil();
}
utarray_free(cb_arg.matched_replies);
- cb_arg.matched_replies=NULL;
- cb_arg.pattern=NULL;
+ cb_arg.matched_replies = NULL;
+ cb_arg.pattern = NULL;
return FINISHED;
}
enum cmd_exec_result crdt_exists_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-//CRDT EXISTS key
- sds key=cmd->argv[2];
- struct sobj *obj=NULL;
- obj=store_lookup(mod_store, key);
- *reply=swarmkv_reply_new_integer((obj && obj->type!=OBJ_TYPE_UNDEFINED)?1:0);
+ // CRDT EXISTS key
+ sds key = cmd->argv[2];
+ struct sobj *obj = NULL;
+ obj = store_lookup(mod_store, key);
+ *reply = swarmkv_reply_new_integer((obj && obj->type != OBJ_TYPE_UNDEFINED) ? 1 : 0);
return FINISHED;
}
-
enum cmd_exec_result crdt_rlist_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* CRDT RLIST key*/
- const sds key=cmd->argv[2];
- struct scontainer *ctr=NULL;
- struct swarmkv_store *store=module2store(mod_store);
- ctr=store_lookup_scontainer(store, key);
- if(!ctr)
+ /* CRDT RLIST key*/
+ const sds key = cmd->argv[2];
+ struct scontainer *ctr = NULL;
+ struct swarmkv_store *store = module2store(mod_store);
+ ctr = store_lookup_scontainer(store, key);
+ if (!ctr)
{
- *reply=swarmkv_reply_new_nil();
+ *reply = swarmkv_reply_new_nil();
return FINISHED;
}
- if(!ctr->replica_node_list)
+ if (!ctr->replica_node_list)
{
- *reply=swarmkv_reply_new_array(0);
+ *reply = swarmkv_reply_new_array(0);
return FINISHED;
}
- *reply=swarmkv_reply_new_array(utarray_len(ctr->replica_node_list));
- for(size_t i=0; i< (*reply)->n_element; i++)
+ *reply = swarmkv_reply_new_array(utarray_len(ctr->replica_node_list));
+ for (size_t i = 0; i < (*reply)->n_element; i++)
{
- (*reply)->elements[i]=swarmkv_reply_new_node(utarray_eltptr(ctr->replica_node_list, i), 0);
+ (*reply)->elements[i] = swarmkv_reply_new_node(utarray_eltptr(ctr->replica_node_list, i), 0);
}
return FINISHED;
}
enum cmd_exec_result crdt_info_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*CRDT INFO key*/
- const sds key=cmd->argv[2];
- struct scontainer *ctr=NULL;
- struct swarmkv_store *store=module2store(mod_store);
- ctr=store_lookup_scontainer(store, key);
- if(!ctr)
+ /*CRDT INFO key*/
+ const sds key = cmd->argv[2];
+ struct scontainer *ctr = NULL;
+ struct swarmkv_store *store = module2store(mod_store);
+ ctr = store_lookup_scontainer(store, key);
+ if (!ctr)
{
- *reply=swarmkv_reply_new_array(0);
+ *reply = swarmkv_reply_new_array(0);
return FINISHED;
}
- size_t sz=0;
- sz+=sobj_specs[ctr->obj.type].obj_size(ctr->obj.raw);
- sz+=sizeof(struct scontainer)+sdslen(ctr->obj.key);
- size_t n_peer=0;
- n_peer=ctr->replica_node_list?utarray_len(ctr->replica_node_list):0;
- sz+=n_peer*sizeof(node_t);
- int i=0;
- *reply=swarmkv_reply_new_array(8);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Type");
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt(sobj_specs[ctr->obj.type].type_name);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Size");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(sz);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Peers");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(n_peer);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("LastModified");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(ctr->op_timestamp.tv_sec);
+ size_t sz = 0;
+ sz += sobj_specs[ctr->obj.type].obj_size(ctr->obj.raw);
+ sz += sizeof(struct scontainer) + sdslen(ctr->obj.key);
+ size_t n_peer = 0;
+ n_peer = ctr->replica_node_list ? utarray_len(ctr->replica_node_list) : 0;
+ sz += n_peer * sizeof(node_t);
+ int i = 0;
+ *reply = swarmkv_reply_new_array(8);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Type");
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt(sobj_specs[ctr->obj.type].type_name);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Size");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(sz);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Peers");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(n_peer);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("LastModified");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(ctr->op_timestamp.tv_sec);
return FINISHED;
}
diff --git a/src/swarmkv_sync.c b/src/swarmkv_sync.c
index a47f931..15eecc0 100644
--- a/src/swarmkv_sync.c
+++ b/src/swarmkv_sync.c
@@ -14,11 +14,11 @@ struct sync_data
};
struct sync_data *sync_data_new(const sds key, char *blob, size_t blob_sz)
{
- struct sync_data *data=ALLOC(struct sync_data, 1);
- data->key=sdsdup(key);
- data->blob=blob;
- data->blob_sz=blob_sz;
- data->ref_cnt=1;
+ struct sync_data *data = ALLOC(struct sync_data, 1);
+ data->key = sdsdup(key);
+ data->blob = blob;
+ data->blob_sz = blob_sz;
+ data->ref_cnt = 1;
return data;
}
void sync_data_ref_inc(struct sync_data *data)
@@ -29,11 +29,11 @@ void sync_data_ref_inc(struct sync_data *data)
void sync_data_free(struct sync_data *data)
{
data->ref_cnt--;
- if(data->ref_cnt==0)
+ if (data->ref_cnt == 0)
{
sdsfree(data->key);
free(data->blob);
- data->blob_sz=0;
+ data->blob_sz = 0;
free(data);
}
return;
@@ -53,39 +53,39 @@ struct sync_master
};
struct sync_master *sync_master_new(void)
{
- struct sync_master *master=ALLOC(struct sync_master, 1);
+ struct sync_master *master = ALLOC(struct sync_master, 1);
return master;
}
-//add_obj take the ownership of the blob
+// add_obj take the ownership of the blob
void sync_master_add_obj(struct sync_master *master, const sds key, char *blob, size_t blob_sz, const node_t *peers, size_t n_peer)
{
- struct sync_task *task=NULL;
- struct sync_data *data=NULL;
- data=sync_data_new(key, blob, blob_sz);
- for(size_t i=0; i<n_peer; i++)
+ struct sync_task *task = NULL;
+ struct sync_data *data = NULL;
+ data = sync_data_new(key, blob, blob_sz);
+ for (size_t i = 0; i < n_peer; i++)
{
- HASH_FIND(hh, master->task_table, peers+i, sizeof(node_t), task);
- if(!task)
+ HASH_FIND(hh, master->task_table, peers + i, sizeof(node_t), task);
+ if (!task)
{
- task=ALLOC(struct sync_task, 1);
- node_copy(&task->peer, peers+i);
+ task = ALLOC(struct sync_task, 1);
+ node_copy(&task->peer, peers + i);
utarray_new(task->sync_data_list, &ut_sync_data_pointer_icd);
HASH_ADD_KEYPTR(hh, master->task_table, &task->peer, sizeof(node_t), task);
}
sync_data_ref_inc(data);
utarray_push_back(task->sync_data_list, &data);
}
- //dereference data
+ // dereference data
sync_data_free(data);
- master->to_sync+=n_peer;
+ master->to_sync += n_peer;
return;
}
struct sync_task *sync_master_get_task(struct sync_master *master)
{
- struct sync_task *task=NULL, *tmp=NULL;
+ struct sync_task *task = NULL, *tmp = NULL;
- //We are not iterating the whole table, just get the first one
+ // We are not iterating the whole table, just get the first one
HASH_ITER(hh, master->task_table, task, tmp)
{
HASH_DEL(master->task_table, task);
@@ -96,12 +96,12 @@ struct sync_task *sync_master_get_task(struct sync_master *master)
}
void sync_task_free(struct sync_task *task)
{
- struct sync_data **p=NULL, *data=NULL;
- size_t n_data=utarray_len(task->sync_data_list);
- for(size_t i=0; i<n_data; i++)
+ struct sync_data **p = NULL, *data = NULL;
+ size_t n_data = utarray_len(task->sync_data_list);
+ for (size_t i = 0; i < n_data; i++)
{
- p=utarray_eltptr(task->sync_data_list, i);
- data=*p;
+ p = utarray_eltptr(task->sync_data_list, i);
+ data = *p;
sync_data_free(data);
}
utarray_free(task->sync_data_list);
@@ -118,27 +118,27 @@ size_t sync_task_key_count(struct sync_task *task)
}
void sync_task_read_key_blob(struct sync_task *task, const char *argv[], size_t *argv_len, int argc)
{
- struct sync_data **p=NULL, *data=NULL;
- int n_data=utarray_len(task->sync_data_list);
- assert(argc == 2*n_data);
- for(int i=0, j=0; i<n_data && j<argc; i++, j+=2)
+ struct sync_data **p = NULL, *data = NULL;
+ int n_data = utarray_len(task->sync_data_list);
+ assert(argc == 2 * n_data);
+ for (int i = 0, j = 0; i < n_data && j < argc; i++, j += 2)
{
- p=utarray_eltptr(task->sync_data_list, i);
- data=*p;
+ p = utarray_eltptr(task->sync_data_list, i);
+ data = *p;
assert(data->key);
assert(data->blob);
- argv[j]=data->key;
- argv_len[j]=sdslen(data->key);
- argv[j+1]=data->blob;
- argv_len[j+1]=data->blob_sz;
+ argv[j] = data->key;
+ argv_len[j] = sdslen(data->key);
+ argv[j + 1] = data->blob;
+ argv_len[j + 1] = data->blob_sz;
}
return;
}
void sync_master_free(struct sync_master *master)
{
- size_t __attribute__((__unused__))task_cnt=HASH_COUNT(master->task_table);
- assert(task_cnt==0);
- assert(master->to_sync==master->synced);
+ size_t __attribute__((__unused__)) task_cnt = HASH_COUNT(master->task_table);
+ assert(task_cnt == 0);
+ assert(master->to_sync == master->synced);
free(master);
return;
} \ No newline at end of file
diff --git a/src/swarmkv_utils.c b/src/swarmkv_utils.c
index adbd188..d1de161 100644
--- a/src/swarmkv_utils.c
+++ b/src/swarmkv_utils.c
@@ -2,76 +2,84 @@
#include <stdio.h>
#include <unistd.h>
#include <time.h>
-#include <sys/syscall.h> /* For SYS_xxx definitions */
+#include <sys/syscall.h> /* For SYS_xxx definitions */
#include <pthread.h>
#include <asm/errno.h>
-#include <ctype.h> //tolower, toupper
+#include <ctype.h> //tolower, toupper
#include <string.h> //memset
#include <stdlib.h>
pid_t gettid()
{
- return syscall(SYS_gettid);
+ return syscall(SYS_gettid);
}
-const char* module_name_str(const char*name)
+const char *module_name_str(const char *name)
{
- static __thread char module[64];
- snprintf(module,sizeof(module),"%s(%d)", name, gettid());
- return module;
+ static __thread char module[64];
+ snprintf(module, sizeof(module), "%s(%d)", name, gettid());
+ return module;
}
-const char* swarmkv_util_pthread_cond_timedwait_error_to_string(const int timed_wait_rv)
+const char *swarmkv_util_pthread_cond_timedwait_error_to_string(const int timed_wait_rv)
{
switch (timed_wait_rv)
{
- case ETIMEDOUT:
- return "Conditional timed failed, the time specified by abstime to pthread_cond_timedwait() has passed.";
- break;
- case EINVAL:
- return "Conditional timed failed, the value specified by abstime, cond or mutex is invalid.";
- break;
- case EPERM:
- return "Conditional timed failed, the mutex was not owned by the current thread at the time of the call.";
- break;
- default:
- break;
+ case ETIMEDOUT:
+ return "Conditional timed failed, the time specified by abstime to pthread_cond_timedwait() has passed.";
+ break;
+ case EINVAL:
+ return "Conditional timed failed, the value specified by abstime, cond or mutex is invalid.";
+ break;
+ case EPERM:
+ return "Conditional timed failed, the mutex was not owned by the current thread at the time of the call.";
+ break;
+ default:
+ break;
}
- return "Conditional timed failed, unknown reason.";
+ return "Conditional timed failed, unknown reason.";
}
-char* toLower(char* s)
+char *toLower(char *s)
{
- for(char *p=s; *p; p++) *p=tolower(*p);
- return s;
+ for (char *p = s; *p; p++)
+ *p = tolower(*p);
+ return s;
}
-char* toUpper(char* s)
+char *toUpper(char *s)
{
- for(char *p=s; *p; p++) *p=toupper(*p);
- return s;
+ for (char *p = s; *p; p++)
+ *p = toupper(*p);
+ return s;
}
-char* replace_char(char* str, char find, char replace){
- char *current_pos = strchr(str,find);
- while (current_pos) {
+char *replace_char(char *str, char find, char replace)
+{
+ char *current_pos = strchr(str, find);
+ while (current_pos)
+ {
*current_pos = replace;
- current_pos = strchr(current_pos,find);
+ current_pos = strchr(current_pos, find);
}
return str;
}
-//source https://github.com/redis/redis/blob/7.0/src/util.c
+// source https://github.com/redis/redis/blob/7.0/src/util.c
int stringmatchlen(const char *pattern, int patternLen,
- const char *string, int stringLen, int nocase)
+ const char *string, int stringLen, int nocase)
{
- while(patternLen && stringLen) {
- switch(pattern[0]) {
+ while (patternLen && stringLen)
+ {
+ switch (pattern[0])
+ {
case '*':
- while (patternLen && pattern[1] == '*') {
+ while (patternLen && pattern[1] == '*')
+ {
pattern++;
patternLen--;
}
if (patternLen == 1)
return 1; /* match */
- while(stringLen) {
- if (stringmatchlen(pattern+1, patternLen-1,
- string, stringLen, nocase))
+ while (stringLen)
+ {
+ if (stringmatchlen(pattern + 1, patternLen - 1,
+ string, stringLen, nocase))
return 1; /* match */
string++;
stringLen--;
@@ -89,33 +97,44 @@ int stringmatchlen(const char *pattern, int patternLen,
pattern++;
patternLen--;
not = pattern[0] == '^';
- if (not) {
+ if (not )
+ {
pattern++;
patternLen--;
}
match = 0;
- while(1) {
- if (pattern[0] == '\\' && patternLen >= 2) {
+ while (1)
+ {
+ if (pattern[0] == '\\' && patternLen >= 2)
+ {
pattern++;
patternLen--;
if (pattern[0] == string[0])
match = 1;
- } else if (pattern[0] == ']') {
+ }
+ else if (pattern[0] == ']')
+ {
break;
- } else if (patternLen == 0) {
+ }
+ else if (patternLen == 0)
+ {
pattern--;
patternLen++;
break;
- } else if (patternLen >= 3 && pattern[1] == '-') {
+ }
+ else if (patternLen >= 3 && pattern[1] == '-')
+ {
int start = pattern[0];
int end = pattern[2];
int c = string[0];
- if (start > end) {
+ if (start > end)
+ {
int t = start;
start = end;
end = t;
}
- if (nocase) {
+ if (nocase)
+ {
start = tolower(start);
end = tolower(end);
c = tolower(c);
@@ -124,11 +143,16 @@ int stringmatchlen(const char *pattern, int patternLen,
patternLen -= 2;
if (c >= start && c <= end)
match = 1;
- } else {
- if (!nocase) {
+ }
+ else
+ {
+ if (!nocase)
+ {
if (pattern[0] == string[0])
match = 1;
- } else {
+ }
+ else
+ {
if (tolower((int)pattern[0]) == tolower((int)string[0]))
match = 1;
}
@@ -136,7 +160,7 @@ int stringmatchlen(const char *pattern, int patternLen,
pattern++;
patternLen--;
}
- if (not)
+ if (not )
match = !match;
if (!match)
return 0; /* no match */
@@ -145,16 +169,20 @@ int stringmatchlen(const char *pattern, int patternLen,
break;
}
case '\\':
- if (patternLen >= 2) {
+ if (patternLen >= 2)
+ {
pattern++;
patternLen--;
}
/* fall through */
default:
- if (!nocase) {
+ if (!nocase)
+ {
if (pattern[0] != string[0])
return 0; /* no match */
- } else {
+ }
+ else
+ {
if (tolower((int)pattern[0]) != tolower((int)string[0]))
return 0; /* no match */
}
@@ -164,8 +192,10 @@ int stringmatchlen(const char *pattern, int patternLen,
}
pattern++;
patternLen--;
- if (stringLen == 0) {
- while(*pattern == '*') {
+ if (stringLen == 0)
+ {
+ while (*pattern == '*')
+ {
pattern++;
patternLen--;
}
@@ -178,36 +208,38 @@ int stringmatchlen(const char *pattern, int patternLen,
}
/* Return the UNIX time in microseconds */
-long long ustime(void) {
+long long ustime(void)
+{
struct timespec tv;
long long ust;
clock_gettime(CLOCK_REALTIME, &tv);
ust = ((long long)tv.tv_sec) * 1000000;
- ust += tv.tv_nsec/1000;
+ ust += tv.tv_nsec / 1000;
return ust;
}
int is_number(const char *string, size_t sz, long long *number)
{
- if(sz>20) return 0;
+ if (sz > 20)
+ return 0;
- for(size_t i=0; i<sz ; i++)
+ for (size_t i = 0; i < sz; i++)
{
- if((string[i]<'0' || string[i]>'9') && string[i]!='-')
+ if ((string[i] < '0' || string[i] > '9') && string[i] != '-')
{
return 0;
}
- if(string[i]=='\0' && i<sz-1)
+ if (string[i] == '\0' && i < sz - 1)
{
return 0;
}
}
- char *endptr=NULL;
- *number=strtol(string, &endptr, 10);
- if(*endptr=='\0')
- {
- return 1;
- }
+ char *endptr = NULL;
+ *number = strtol(string, &endptr, 10);
+ if (*endptr == '\0')
+ {
+ return 1;
+ }
else
{
return 0;
@@ -215,12 +247,12 @@ int is_number(const char *string, size_t sz, long long *number)
}
int is_double(const char *string, double *number)
{
- char *endptr=NULL;
+ char *endptr = NULL;
*number = strtod(string, &endptr);
- if(*endptr=='\0')
- {
- return 1;
- }
+ if (*endptr == '\0')
+ {
+ return 1;
+ }
else
{
return 0;
diff --git a/src/t_bloom_filter.c b/src/t_bloom_filter.c
index 58db58b..e6bc4ae 100644
--- a/src/t_bloom_filter.c
+++ b/src/t_bloom_filter.c
@@ -9,220 +9,220 @@
enum cmd_exec_result bfinit_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* BFINIT key error capacity [TIME window-milliseconds slice-number] */
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
+ /* BFINIT key error capacity [TIME window-milliseconds slice-number] */
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
- double error_rate=0;
- long long capacity=0, time_window_ms=0, time_slice_num=0;
+ double error_rate = 0;
+ long long capacity = 0, time_window_ms = 0, time_slice_num = 0;
- int ret=0;
- error_rate=strtod(cmd->argv[2], NULL);
- if(error_rate < 0 || error_rate >= 1.0)
+ int ret = 0;
+ error_rate = strtod(cmd->argv[2], NULL);
+ if (error_rate < 0 || error_rate >= 1.0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_float, cmd->argv[2]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_float, cmd->argv[2]);
return FINISHED;
}
- ret=str2integer(cmd->argv[3], &capacity);
- if(ret<0)
+ ret = str2integer(cmd->argv[3], &capacity);
+ if (ret < 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[3]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[3]);
}
- if(cmd->argc==7)
+ if (cmd->argc == 7)
{
- if(strncasecmp(cmd->argv[4], "TIME", 4)!=0)
+ if (strncasecmp(cmd->argv[4], "TIME", 4) != 0)
{
- *reply=swarmkv_reply_new_error(error_arg_string_should_be, cmd->argv[4], "TIME");
+ *reply = swarmkv_reply_new_error(error_arg_string_should_be, cmd->argv[4], "TIME");
return FINISHED;
}
- ret=str2integer(cmd->argv[5], &time_window_ms);
- if(ret<0)
+ ret = str2integer(cmd->argv[5], &time_window_ms);
+ if (ret < 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[5]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[5]);
return FINISHED;
}
- ret=str2integer(cmd->argv[6], &time_slice_num);
- if(ret<0 || time_slice_num<0)
+ ret = str2integer(cmd->argv[6], &time_slice_num);
+ if (ret < 0 || time_slice_num < 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[6]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[6]);
return FINISHED;
}
}
- obj=store_lookup(mod_store, key);
- if(!obj)
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
-
- if(obj->type==OBJ_TYPE_UNDEFINED)
+
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
- assert(obj->raw==NULL);
- obj->bloom=AP_bloom_new(now, error_rate, capacity, time_window_ms, time_slice_num);
- obj->type=OBJ_TYPE_BLOOM_FILTER;
- *reply=swarmkv_reply_new_status("OK");
+ assert(obj->raw == NULL);
+ obj->bloom = AP_bloom_new(now, error_rate, capacity, time_window_ms, time_slice_num);
+ obj->type = OBJ_TYPE_BLOOM_FILTER;
+ *reply = swarmkv_reply_new_status("OK");
}
else
{
- *reply=swarmkv_reply_new_array(0);
+ *reply = swarmkv_reply_new_array(0);
}
return FINISHED;
}
enum cmd_exec_result bfadd_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*BFADD key item [item ...]*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
+ /*BFADD key item [item ...]*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
-
- if(obj->type==OBJ_TYPE_UNDEFINED)
+
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- else if(obj->type!=OBJ_TYPE_BLOOM_FILTER)
+ else if (obj->type != OBJ_TYPE_BLOOM_FILTER)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
- for(int i=0; i<cmd->argc-2; i++)
+ for (int i = 0; i < cmd->argc - 2; i++)
{
- AP_bloom_add(obj->bloom, now, cmd->argv[i+2], sdslen(cmd->argv[i+2]));
+ AP_bloom_add(obj->bloom, now, cmd->argv[i + 2], sdslen(cmd->argv[i + 2]));
}
store_mark_object_as_modified(mod_store, obj);
- *reply=swarmkv_reply_new_status("OK");
+ *reply = swarmkv_reply_new_status("OK");
return FINISHED;
}
enum cmd_exec_result bfmexists_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*BFMEXISTS key item [item ...]*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ /*BFMEXISTS key item [item ...]*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
- if(obj->type==OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- else if(obj->type!=OBJ_TYPE_BLOOM_FILTER)
+ else if (obj->type != OBJ_TYPE_BLOOM_FILTER)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
- long long exists=0;
- *reply=swarmkv_reply_new_array(cmd->argc-2);
- for(int i=0; i<cmd->argc-2; i++)
+ long long exists = 0;
+ *reply = swarmkv_reply_new_array(cmd->argc - 2);
+ for (int i = 0; i < cmd->argc - 2; i++)
{
- exists = AP_bloom_check(obj->bloom, now, cmd->argv[i+2], sdslen(cmd->argv[i+2]));
- (*reply)->elements[i]=swarmkv_reply_new_integer(exists);
+ exists = AP_bloom_check(obj->bloom, now, cmd->argv[i + 2], sdslen(cmd->argv[i + 2]));
+ (*reply)->elements[i] = swarmkv_reply_new_integer(exists);
}
return FINISHED;
}
enum cmd_exec_result bfexists_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- enum cmd_exec_result ret;
- struct swarmkv_reply *tmp_reply=NULL;
- ret=bfmexists_command(mod_store, cmd, &tmp_reply);
- if(ret==FINISHED)
- {
- if(tmp_reply->type==SWARMKV_REPLY_ARRAY)
- {
- *reply=swarmkv_reply_dup(tmp_reply->elements[0]);
- swarmkv_reply_free(tmp_reply);
- }
- else
- {
- *reply=tmp_reply;
- }
- }
- return ret;
+ enum cmd_exec_result ret;
+ struct swarmkv_reply *tmp_reply = NULL;
+ ret = bfmexists_command(mod_store, cmd, &tmp_reply);
+ if (ret == FINISHED)
+ {
+ if (tmp_reply->type == SWARMKV_REPLY_ARRAY)
+ {
+ *reply = swarmkv_reply_dup(tmp_reply->elements[0]);
+ swarmkv_reply_free(tmp_reply);
+ }
+ else
+ {
+ *reply = tmp_reply;
+ }
+ }
+ return ret;
}
enum cmd_exec_result bfcard_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*BFCARD key*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ /*BFCARD key*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
- if(obj->type==OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- else if(obj->type!=OBJ_TYPE_BLOOM_FILTER)
+ else if (obj->type != OBJ_TYPE_BLOOM_FILTER)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
- long long cardinality=0;
- cardinality=AP_bloom_cardinality(obj->bloom);
- *reply=swarmkv_reply_new_integer(cardinality);
+ long long cardinality = 0;
+ cardinality = AP_bloom_cardinality(obj->bloom);
+ *reply = swarmkv_reply_new_integer(cardinality);
return FINISHED;
}
enum cmd_exec_result bfinfo_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*BFINFO key*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ /*BFINFO key*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
- if(obj->type==OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- else if(obj->type!=OBJ_TYPE_BLOOM_FILTER)
+ else if (obj->type != OBJ_TYPE_BLOOM_FILTER)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
struct AP_bloom_info info;
AP_bloom_info(obj->bloom, &info);
- int i=0;
- *reply=swarmkv_reply_new_array(20);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Error");
- (*reply)->elements[i++]=swarmkv_reply_new_double(info.error);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Capacity");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(info.capacity);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("TimeWindowMs");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(info.time_window_ms);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("TimeSlices");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(info.time_slice_num);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("HashNum");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(info.hash_num);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("TotalSlices");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(info.total_slice_number);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("MaxExpansionTimes");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(info.max_expand_times);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("ApproximateItemNum");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(info.approximate_item_num);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("FillRatio");
- (*reply)->elements[i++]=swarmkv_reply_new_double(info.fill_ratio);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("OldestItemTime");
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("%lld.%03lld", info.oldest_item_time.tv_sec, info.oldest_item_time.tv_usec/1000);
- assert(i==20);
+ int i = 0;
+ *reply = swarmkv_reply_new_array(20);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Error");
+ (*reply)->elements[i++] = swarmkv_reply_new_double(info.error);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Capacity");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(info.capacity);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("TimeWindowMs");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(info.time_window_ms);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("TimeSlices");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(info.time_slice_num);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("HashNum");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(info.hash_num);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("TotalSlices");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(info.total_slice_number);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("MaxExpansionTimes");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(info.max_expand_times);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("ApproximateItemNum");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(info.approximate_item_num);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("FillRatio");
+ (*reply)->elements[i++] = swarmkv_reply_new_double(info.fill_ratio);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("OldestItemTime");
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("%lld.%03lld", info.oldest_item_time.tv_sec, info.oldest_item_time.tv_usec / 1000);
+ assert(i == 20);
return FINISHED;
} \ No newline at end of file
diff --git a/src/t_cms.c b/src/t_cms.c
index cb0f8dd..e007acd 100644
--- a/src/t_cms.c
+++ b/src/t_cms.c
@@ -9,314 +9,314 @@
enum cmd_exec_result cmsinitbydim_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* CMSINITBYDIM key width depth*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
+ /* CMSINITBYDIM key width depth*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
- long long width=0, depth=0;
+ long long width = 0, depth = 0;
- width=strtol(cmd->argv[2], NULL, 10);
- if(width<=0)
- {
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
- return FINISHED;
- }
- depth=strtol(cmd->argv[3], NULL, 10);
- if(depth<=0)
- {
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[3]);
- return FINISHED;
- }
- obj=store_lookup(mod_store, key);
- if(!obj)
- {
- return NEED_KEY_ROUTE;
+ width = strtol(cmd->argv[2], NULL, 10);
+ if (width <= 0)
+ {
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
+ return FINISHED;
+ }
+ depth = strtol(cmd->argv[3], NULL, 10);
+ if (depth <= 0)
+ {
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[3]);
+ return FINISHED;
+ }
+ obj = store_lookup(mod_store, key);
+ if (!obj)
+ {
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
-
- if(obj->type==OBJ_TYPE_UNDEFINED)
+
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
- assert(obj->raw==NULL);
- uuid_t uuid;
- store_get_uuid(mod_store, uuid);
- obj->cms=CM_sketch_new(uuid, width, depth);
- obj->type=OBJ_TYPE_CMS;
- *reply=swarmkv_reply_new_status("OK");
+ assert(obj->raw == NULL);
+ uuid_t uuid;
+ store_get_uuid(mod_store, uuid);
+ obj->cms = CM_sketch_new(uuid, width, depth);
+ obj->type = OBJ_TYPE_CMS;
+ *reply = swarmkv_reply_new_status("OK");
}
else
{
- *reply=swarmkv_reply_new_array(0);
+ *reply = swarmkv_reply_new_array(0);
}
return FINISHED;
}
enum cmd_exec_result cmsinitbyprob_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* CMSINITBYPROB key error probability*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
+ /* CMSINITBYPROB key error probability*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
- double error=0, probability=0;
- error=strtod(cmd->argv[2], NULL);
- if(error < 0 || error >= 1.0)
+ double error = 0, probability = 0;
+ error = strtod(cmd->argv[2], NULL);
+ if (error < 0 || error >= 1.0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_float, cmd->argv[2]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_float, cmd->argv[2]);
return FINISHED;
}
- probability=strtod(cmd->argv[3], NULL);
- if(probability < 0 || probability >= 1.0)
+ probability = strtod(cmd->argv[3], NULL);
+ if (probability < 0 || probability >= 1.0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_float, cmd->argv[3]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_float, cmd->argv[3]);
return FINISHED;
}
- int width=0, depth=0;
+ int width = 0, depth = 0;
CM_sketch_tool_dimension_by_prob(error, probability, &width, &depth);
- obj=store_lookup(mod_store, key);
- if(!obj)
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
-
- if(obj->type==OBJ_TYPE_UNDEFINED)
+
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
- assert(obj->raw==NULL);
- uuid_t uuid;
- store_get_uuid(mod_store, uuid);
- obj->cms=CM_sketch_new(uuid, width, depth);
- obj->type=OBJ_TYPE_CMS;
- *reply=swarmkv_reply_new_status("OK");
+ assert(obj->raw == NULL);
+ uuid_t uuid;
+ store_get_uuid(mod_store, uuid);
+ obj->cms = CM_sketch_new(uuid, width, depth);
+ obj->type = OBJ_TYPE_CMS;
+ *reply = swarmkv_reply_new_status("OK");
}
else
{
- *reply=swarmkv_reply_new_array(0);
+ *reply = swarmkv_reply_new_array(0);
}
return FINISHED;
}
static int parse_incrby_args(const struct swarmkv_cmd *cmd, long long *increments, size_t n_increment, int *invalid_idx)
{
- assert(n_increment == (cmd->argc-2)/2);
- char *endptr=NULL;
- for(int i=3, j=0; i<cmd->argc; i+=2, j++)
- {
- *invalid_idx=i;
- increments[j]=strtol(cmd->argv[i], &endptr, 10);
- if(*endptr != '\0')
- {
- return -1;
- }
- if(increments[j] > INT32_MAX || increments[j] < INT32_MIN)
- {
- return -1;
- }
- }
- return 0;
+ assert(n_increment == (cmd->argc - 2) / 2);
+ char *endptr = NULL;
+ for (int i = 3, j = 0; i < cmd->argc; i += 2, j++)
+ {
+ *invalid_idx = i;
+ increments[j] = strtol(cmd->argv[i], &endptr, 10);
+ if (*endptr != '\0')
+ {
+ return -1;
+ }
+ if (increments[j] > INT32_MAX || increments[j] < INT32_MIN)
+ {
+ return -1;
+ }
+ }
+ return 0;
}
enum cmd_exec_result cmsincrby_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*CMSINCRBY key item increment [item increment ...]*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ /*CMSINCRBY key item increment [item increment ...]*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
-
- if(obj->type==OBJ_TYPE_UNDEFINED)
+
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
assert(obj->raw == NULL);
return handle_undefined_object(obj, reply);
}
- else if(obj->type!=OBJ_TYPE_CMS)
+ else if (obj->type != OBJ_TYPE_CMS)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
- size_t n_increment=(cmd->argc-2)/2;
- long long increments[n_increment], query[n_increment];
- int ret=0, invalid_idx=0;
- ret = parse_incrby_args(cmd, increments, n_increment, &invalid_idx);
- if(ret<0)
- {
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[invalid_idx]);
- return FINISHED;
- }
- *reply=swarmkv_reply_new_array(n_increment);
- for(int i=2, j=0; i<cmd->argc; i+=2, j++)
- {
- query[j]=CM_sketch_incrby(obj->cms, cmd->argv[i], sdslen(cmd->argv[i]), (int) increments[j]);
- (*reply)->elements[j]=swarmkv_reply_new_integer(query[j]);
+ size_t n_increment = (cmd->argc - 2) / 2;
+ long long increments[n_increment], query[n_increment];
+ int ret = 0, invalid_idx = 0;
+ ret = parse_incrby_args(cmd, increments, n_increment, &invalid_idx);
+ if (ret < 0)
+ {
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[invalid_idx]);
+ return FINISHED;
+ }
+ *reply = swarmkv_reply_new_array(n_increment);
+ for (int i = 2, j = 0; i < cmd->argc; i += 2, j++)
+ {
+ query[j] = CM_sketch_incrby(obj->cms, cmd->argv[i], sdslen(cmd->argv[i]), (int)increments[j]);
+ (*reply)->elements[j] = swarmkv_reply_new_integer(query[j]);
}
store_mark_object_as_modified(mod_store, obj);
return FINISHED;
}
enum cmd_exec_result cmsmquery_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*CMSMQUERY key item [item ...]*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
+ /*CMSMQUERY key item [item ...]*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
-
- if(obj->type==OBJ_TYPE_UNDEFINED)
+
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- else if(obj->type!=OBJ_TYPE_CMS)
+ else if (obj->type != OBJ_TYPE_CMS)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
- *reply=swarmkv_reply_new_array(cmd->argc-2);
- for(int i=0; i<cmd->argc-2; i++)
+ *reply = swarmkv_reply_new_array(cmd->argc - 2);
+ for (int i = 0; i < cmd->argc - 2; i++)
{
- int query=0;
- query=CM_sketch_query(obj->cms, cmd->argv[i+2], sdslen(cmd->argv[i+2]));
- (*reply)->elements[i]=swarmkv_reply_new_integer(query);
+ int query = 0;
+ query = CM_sketch_query(obj->cms, cmd->argv[i + 2], sdslen(cmd->argv[i + 2]));
+ (*reply)->elements[i] = swarmkv_reply_new_integer(query);
}
return FINISHED;
}
enum cmd_exec_result cmsquery_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- enum cmd_exec_result ret;
- struct swarmkv_reply *tmp_reply=NULL;
- ret=cmsmquery_command(mod_store, cmd, &tmp_reply);
- if(ret==FINISHED)
- {
- if(tmp_reply->type==SWARMKV_REPLY_ARRAY)
- {
- *reply=swarmkv_reply_dup(tmp_reply->elements[0]);
- swarmkv_reply_free(tmp_reply);
- }
- else
- {
- *reply=tmp_reply;
- }
- }
- return ret;
+ enum cmd_exec_result ret;
+ struct swarmkv_reply *tmp_reply = NULL;
+ ret = cmsmquery_command(mod_store, cmd, &tmp_reply);
+ if (ret == FINISHED)
+ {
+ if (tmp_reply->type == SWARMKV_REPLY_ARRAY)
+ {
+ *reply = swarmkv_reply_dup(tmp_reply->elements[0]);
+ swarmkv_reply_free(tmp_reply);
+ }
+ else
+ {
+ *reply = tmp_reply;
+ }
+ }
+ return ret;
}
enum cmd_exec_result cmsinfo_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*CMSINFO key*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ /*CMSINFO key*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
- if(obj->type==OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- else if(obj->type!=OBJ_TYPE_CMS)
+ else if (obj->type != OBJ_TYPE_CMS)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
struct CM_sketch_info info;
CM_sketch_info(obj->cms, &info);
- int i=0;
- *reply=swarmkv_reply_new_array(12);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Width");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(info.width);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Depth");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(info.depth);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Error");
- (*reply)->elements[i++]=swarmkv_reply_new_double(info.error);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Probability");
- (*reply)->elements[i++]=swarmkv_reply_new_double(info.probability);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Count");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(info.count);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("ReplicaNumber");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(info.n_replica);
- assert(i==12);
+ int i = 0;
+ *reply = swarmkv_reply_new_array(12);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Width");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(info.width);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Depth");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(info.depth);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Error");
+ (*reply)->elements[i++] = swarmkv_reply_new_double(info.error);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Probability");
+ (*reply)->elements[i++] = swarmkv_reply_new_double(info.probability);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Count");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(info.count);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("ReplicaNumber");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(info.n_replica);
+ assert(i == 12);
return FINISHED;
}
enum cmd_exec_result cmsrlist_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*CMSRLIST key*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ /*CMSRLIST key*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
- if(obj->type==OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- else if(obj->type!=OBJ_TYPE_CMS)
+ else if (obj->type != OBJ_TYPE_CMS)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
struct CM_sketch_info info;
CM_sketch_info(obj->cms, &info);
uuid_t replicas[info.n_replica];
- size_t n_nodes=0;
+ size_t n_nodes = 0;
CM_sketch_list_replica(obj->cms, replicas, &n_nodes);
- *reply=swarmkv_reply_new_array(n_nodes);
- for(int i=0; i<n_nodes; i++)
+ *reply = swarmkv_reply_new_array(n_nodes);
+ for (int i = 0; i < n_nodes; i++)
{
char uuid_str[37];
uuid_unparse(replicas[i], uuid_str);
- (*reply)->elements[i]=swarmkv_reply_new_string(uuid_str, strlen(uuid_str));
+ (*reply)->elements[i] = swarmkv_reply_new_string(uuid_str, strlen(uuid_str));
}
return FINISHED;
}
enum cmd_exec_result cmsrclear_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*CMSRCLEAR key uuid*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ /*CMSRCLEAR key uuid*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
- if(obj->type==OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- else if(obj->type!=OBJ_TYPE_CMS)
+ else if (obj->type != OBJ_TYPE_CMS)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
uuid_t uuid;
- if(0 > uuid_parse(cmd->argv[2], uuid))
+ if (0 > uuid_parse(cmd->argv[2], uuid))
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_uuid, cmd->argv[2]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_uuid, cmd->argv[2]);
return FINISHED;
}
- int ret=CM_sketch_clear_replica(obj->cms, uuid);
- if(ret<0)
+ int ret = CM_sketch_clear_replica(obj->cms, uuid);
+ if (ret < 0)
{
- *reply=swarmkv_reply_new_error("replica uuid is not exist");
+ *reply = swarmkv_reply_new_error("replica uuid is not exist");
}
else
{
- *reply=swarmkv_reply_new_status("OK");
+ *reply = swarmkv_reply_new_status("OK");
store_mark_object_as_modified(mod_store, obj);
- }
+ }
return FINISHED;
} \ No newline at end of file
diff --git a/src/t_hash.c b/src/t_hash.c
index 120f1ed..a00cc7d 100644
--- a/src/t_hash.c
+++ b/src/t_hash.c
@@ -8,307 +8,309 @@
#include <assert.h>
static struct swarmkv_reply *or_map_kv_to_reply(const struct OR_map_kv *kv)
{
- struct swarmkv_reply *reply=NULL;
- switch(kv->type)
- {
- case TYPE_STRING:
- reply=swarmkv_reply_new_string(kv->string, kv->str_len);
- break;
- case TYPE_INTEGER:
- reply=swarmkv_reply_new_string_from_integer(kv->integer);
- break;
- default:
- reply=swarmkv_reply_new_nil();
- break;
- }
- return reply;
+ struct swarmkv_reply *reply = NULL;
+ switch (kv->type)
+ {
+ case TYPE_STRING:
+ reply = swarmkv_reply_new_string(kv->string, kv->str_len);
+ break;
+ case TYPE_INTEGER:
+ reply = swarmkv_reply_new_string_from_integer(kv->integer);
+ break;
+ default:
+ reply = swarmkv_reply_new_nil();
+ break;
+ }
+ return reply;
}
enum cmd_exec_result hset_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-//HSET key field value [field value ...]
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
-
- obj=store_lookup(mod_store, key);
- if(!obj)
+ // HSET key field value [field value ...]
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
return NEED_KEY_ROUTE;
}
-
- if(obj->type==OBJ_TYPE_UNDEFINED)
+
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
uuid_t uuid;
- assert(obj->raw==NULL);
+ assert(obj->raw == NULL);
store_get_uuid(mod_store, uuid);
- obj->hash=OR_map_new(uuid);
- obj->type=OBJ_TYPE_HASH;
+ obj->hash = OR_map_new(uuid);
+ obj->type = OBJ_TYPE_HASH;
}
- size_t n_to_add=(cmd->argc-2)/2;
- size_t i=0;
- int ret=0, n_added=0;
+ size_t n_to_add = (cmd->argc - 2) / 2;
+ size_t i = 0;
+ int ret = 0, n_added = 0;
- sds field=NULL;
- sds value=NULL;
- long long int_val=0;
+ sds field = NULL;
+ sds value = NULL;
+ long long int_val = 0;
- if(obj->type==OBJ_TYPE_HASH)
+ if (obj->type == OBJ_TYPE_HASH)
{
- for(i=0; i<n_to_add; i++)
+ for (i = 0; i < n_to_add; i++)
{
- field=cmd->argv[2+i*2];
- value=cmd->argv[2+i*2+1];
- if(is_number(value, sdslen(value), &int_val))
+ field = cmd->argv[2 + i * 2];
+ value = cmd->argv[2 + i * 2 + 1];
+ if (is_number(value, sdslen(value), &int_val))
{
- ret=OR_map_set_integer(obj->hash, field, sdslen(field), int_val);
+ ret = OR_map_set_integer(obj->hash, field, sdslen(field), int_val);
}
else
{
- ret=OR_map_set_string(obj->hash, field, sdslen(field),
- value, sdslen(value));
+ ret = OR_map_set_string(obj->hash, field, sdslen(field),
+ value, sdslen(value));
}
- if(ret>0) n_added++;
+ if (ret > 0)
+ n_added++;
}
- *reply=swarmkv_reply_new_integer(n_added);
+ *reply = swarmkv_reply_new_integer(n_added);
store_mark_object_as_modified(mod_store, obj);
}
else
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
- }
+ *reply = swarmkv_reply_new_error(error_wrong_type);
+ }
return FINISHED;
}
enum cmd_exec_result hdel_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- //HDEL key field [field ...]
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
-
- obj=store_lookup(mod_store, key);
- if(!obj)
+ // HDEL key field [field ...]
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
return NEED_KEY_ROUTE;
}
- if(obj->type == OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- if(obj->type!=OBJ_TYPE_HASH)
+ if (obj->type != OBJ_TYPE_HASH)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
- size_t n_to_del=cmd->argc-2;
- size_t i=0;
- int ret=0, n_deleted=0;
+ size_t n_to_del = cmd->argc - 2;
+ size_t i = 0;
+ int ret = 0, n_deleted = 0;
sds field;
- for(i=0; i<n_to_del; i++)
+ for (i = 0; i < n_to_del; i++)
{
- field=cmd->argv[2+i];
- ret=OR_map_remove(obj->hash, field, sdslen(field));
- if(ret>0) n_deleted++;
+ field = cmd->argv[2 + i];
+ ret = OR_map_remove(obj->hash, field, sdslen(field));
+ if (ret > 0)
+ n_deleted++;
}
- *reply=swarmkv_reply_new_integer(n_deleted);
+ *reply = swarmkv_reply_new_integer(n_deleted);
store_mark_object_as_modified(mod_store, obj);
- return FINISHED;
+ return FINISHED;
}
enum cmd_exec_result hmget_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- //HMGET key field [field ...]
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
-
- obj=store_lookup(mod_store, key);
- if(!obj)
+ // HMGET key field [field ...]
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
return NEED_KEY_ROUTE;
}
- if(obj->type == OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- if(obj->type!=OBJ_TYPE_HASH)
+ if (obj->type != OBJ_TYPE_HASH)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
- size_t n_to_get=cmd->argc-2;
- struct OR_map_kv *kv_got=NULL;
- *reply=swarmkv_reply_new_array(n_to_get);
- for(size_t i=0; i<n_to_get; i++)
- {
- kv_got=OR_map_get(obj->hash, cmd->argv[i+2], sdslen(cmd->argv[i+2]));
- if(!kv_got)
- {
- (*reply)->elements[i]=swarmkv_reply_new_nil();
- }
- else
- {
- (*reply)->elements[i]=or_map_kv_to_reply(kv_got);
- OR_map_kv_free(kv_got);
- }
- }
- return FINISHED;
+ size_t n_to_get = cmd->argc - 2;
+ struct OR_map_kv *kv_got = NULL;
+ *reply = swarmkv_reply_new_array(n_to_get);
+ for (size_t i = 0; i < n_to_get; i++)
+ {
+ kv_got = OR_map_get(obj->hash, cmd->argv[i + 2], sdslen(cmd->argv[i + 2]));
+ if (!kv_got)
+ {
+ (*reply)->elements[i] = swarmkv_reply_new_nil();
+ }
+ else
+ {
+ (*reply)->elements[i] = or_map_kv_to_reply(kv_got);
+ OR_map_kv_free(kv_got);
+ }
+ }
+ return FINISHED;
}
enum cmd_exec_result hget_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- enum cmd_exec_result ret;
- struct swarmkv_reply *tmp_reply=NULL;
- ret=hmget_command(mod_store, cmd, &tmp_reply);
- if(ret==FINISHED)
- {
- if(tmp_reply->type==SWARMKV_REPLY_ARRAY)
- {
- *reply=swarmkv_reply_dup(tmp_reply->elements[0]);
- swarmkv_reply_free(tmp_reply);
- }
- else
- {
- *reply=tmp_reply;
- }
- }
- return ret;
+ enum cmd_exec_result ret;
+ struct swarmkv_reply *tmp_reply = NULL;
+ ret = hmget_command(mod_store, cmd, &tmp_reply);
+ if (ret == FINISHED)
+ {
+ if (tmp_reply->type == SWARMKV_REPLY_ARRAY)
+ {
+ *reply = swarmkv_reply_dup(tmp_reply->elements[0]);
+ swarmkv_reply_free(tmp_reply);
+ }
+ else
+ {
+ *reply = tmp_reply;
+ }
+ }
+ return ret;
}
enum cmd_exec_result hgetall_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- //HGETALL key
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
-
- obj=store_lookup(mod_store, key);
- if(!obj)
+ // HGETALL key
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
return NEED_KEY_ROUTE;
}
- if(obj->type == OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- if(obj->type!=OBJ_TYPE_HASH)
+ if (obj->type != OBJ_TYPE_HASH)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
- struct OR_map_kv **kv_list=NULL;
- size_t n_kv=0;
- n_kv=OR_map_get_all(obj->hash, &kv_list);
- *reply=swarmkv_reply_new_array(n_kv*2);
- for(size_t i=0; i<n_kv; i++)
- {
- (*reply)->elements[i*2]=swarmkv_reply_new_string(kv_list[i]->key, kv_list[i]->key_len);
- (*reply)->elements[i*2+1]=or_map_kv_to_reply(kv_list[i]);
+ struct OR_map_kv **kv_list = NULL;
+ size_t n_kv = 0;
+ n_kv = OR_map_get_all(obj->hash, &kv_list);
+ *reply = swarmkv_reply_new_array(n_kv * 2);
+ for (size_t i = 0; i < n_kv; i++)
+ {
+ (*reply)->elements[i * 2] = swarmkv_reply_new_string(kv_list[i]->key, kv_list[i]->key_len);
+ (*reply)->elements[i * 2 + 1] = or_map_kv_to_reply(kv_list[i]);
OR_map_kv_free(kv_list[i]);
- kv_list[i]=NULL;
+ kv_list[i] = NULL;
}
free(kv_list);
- return FINISHED;
+ return FINISHED;
}
enum cmd_exec_result hincrby_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- //HINCRBY key field increment
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
- sds field=cmd->argv[2];
+ // HINCRBY key field increment
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+ sds field = cmd->argv[2];
- long long increment=0;
- if(!is_number(cmd->argv[3], sdslen(cmd->argv[3]), &increment))
+ long long increment = 0;
+ if (!is_number(cmd->argv[3], sdslen(cmd->argv[3]), &increment))
{
- *reply=swarmkv_reply_new_error(error_value_not_integer);
+ *reply = swarmkv_reply_new_error(error_value_not_integer);
return FINISHED;
}
- obj=store_lookup(mod_store, key);
- if(!obj)
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
return NEED_KEY_ROUTE;
}
- if(obj->type==OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
uuid_t uuid;
- assert(obj->raw==NULL);
+ assert(obj->raw == NULL);
store_get_uuid(mod_store, uuid);
- obj->hash=OR_map_new(uuid);
- obj->type=OBJ_TYPE_HASH;
+ obj->hash = OR_map_new(uuid);
+ obj->type = OBJ_TYPE_HASH;
}
- int ret=0;
- long long result=0;
-
- if(obj->type==OBJ_TYPE_HASH)
+ int ret = 0;
+ long long result = 0;
+
+ if (obj->type == OBJ_TYPE_HASH)
{
- ret=OR_map_incrby(obj->hash, field, sdslen(field), increment, &result);
- if(ret<0)
- {
- *reply=swarmkv_reply_new_error(error_wrong_type);
- }
+ ret = OR_map_incrby(obj->hash, field, sdslen(field), increment, &result);
+ if (ret < 0)
+ {
+ *reply = swarmkv_reply_new_error(error_wrong_type);
+ }
else
{
- *reply=swarmkv_reply_new_integer(result);
- store_mark_object_as_modified(mod_store, obj);
- }
+ *reply = swarmkv_reply_new_integer(result);
+ store_mark_object_as_modified(mod_store, obj);
+ }
}
else
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
- }
- return FINISHED;
+ *reply = swarmkv_reply_new_error(error_wrong_type);
+ }
+ return FINISHED;
}
enum cmd_exec_result hkeys_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
-
- obj=store_lookup(mod_store, key);
- if(!obj)
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
return NEED_KEY_ROUTE;
}
- if(obj->type == OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- if(obj->type!=OBJ_TYPE_HASH)
+ if (obj->type != OBJ_TYPE_HASH)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
- struct OR_map_kv **kv_list=NULL;
- size_t n_kv=0;
- n_kv=OR_map_keys(obj->hash, &kv_list);
- *reply=swarmkv_reply_new_array(n_kv);
- for(size_t i=0; i<n_kv; i++)
- {
- (*reply)->elements[i]=swarmkv_reply_new_string(kv_list[i]->key, kv_list[i]->key_len);
+ struct OR_map_kv **kv_list = NULL;
+ size_t n_kv = 0;
+ n_kv = OR_map_keys(obj->hash, &kv_list);
+ *reply = swarmkv_reply_new_array(n_kv);
+ for (size_t i = 0; i < n_kv; i++)
+ {
+ (*reply)->elements[i] = swarmkv_reply_new_string(kv_list[i]->key, kv_list[i]->key_len);
OR_map_kv_free(kv_list[i]);
- kv_list[i]=NULL;
+ kv_list[i] = NULL;
}
free(kv_list);
- return FINISHED;
+ return FINISHED;
}
enum cmd_exec_result hlen_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- //HMGET key
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
-
- obj=store_lookup(mod_store, key);
- if(!obj)
+ // HMGET key
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
return NEED_KEY_ROUTE;
}
- if(obj->type == OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- if(obj->type!=OBJ_TYPE_HASH)
+ if (obj->type != OBJ_TYPE_HASH)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
- size_t n_field=0;
- n_field=OR_map_cardinality(obj->hash);
- *reply=swarmkv_reply_new_integer((long long)n_field);
- return FINISHED;
+ size_t n_field = 0;
+ n_field = OR_map_cardinality(obj->hash);
+ *reply = swarmkv_reply_new_integer((long long)n_field);
+ return FINISHED;
} \ No newline at end of file
diff --git a/src/t_hyperloglog.c b/src/t_hyperloglog.c
index 9e0d8af..667b2be 100644
--- a/src/t_hyperloglog.c
+++ b/src/t_hyperloglog.c
@@ -8,151 +8,150 @@
#include <assert.h>
enum cmd_exec_result pfinit_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* PFINIT key precison [TIME window-milliseconds] */
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
+ /* PFINIT key precison [TIME window-milliseconds] */
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
- long long precision=0, time_window_ms=0;
+ long long precision = 0, time_window_ms = 0;
+ int ret = 0;
+ precision = strtod(cmd->argv[2], NULL);
- int ret=0;
- precision=strtod(cmd->argv[2], NULL);
-
- if(precision < HLL_MIN_PRECISION || precision > HLL_MAX_PRECISION)
+ if (precision < HLL_MIN_PRECISION || precision > HLL_MAX_PRECISION)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
return FINISHED;
}
- if(cmd->argc==5)
+ if (cmd->argc == 5)
{
- if(strncasecmp(cmd->argv[3], "TIME", 4)!=0)
+ if (strncasecmp(cmd->argv[3], "TIME", 4) != 0)
{
- *reply=swarmkv_reply_new_error(error_arg_string_should_be, cmd->argv[4], "TIME");
+ *reply = swarmkv_reply_new_error(error_arg_string_should_be, cmd->argv[4], "TIME");
return FINISHED;
}
- ret=str2integer(cmd->argv[4], &time_window_ms);
- if(ret<0)
+ ret = str2integer(cmd->argv[4], &time_window_ms);
+ if (ret < 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[5]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[5]);
return FINISHED;
}
}
- obj=store_lookup(mod_store, key);
- if(!obj)
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
-
- if(obj->type==OBJ_TYPE_UNDEFINED)
+
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
- assert(obj->raw==NULL);
- obj->hll=ST_hyperloglog_new(precision, time_window_ms, now);
- obj->type=OBJ_TYPE_HYPERLOGLOG;
- *reply=swarmkv_reply_new_status("OK");
+ assert(obj->raw == NULL);
+ obj->hll = ST_hyperloglog_new(precision, time_window_ms, now);
+ obj->type = OBJ_TYPE_HYPERLOGLOG;
+ *reply = swarmkv_reply_new_status("OK");
}
else
{
- *reply=swarmkv_reply_new_array(0);
+ *reply = swarmkv_reply_new_array(0);
}
return FINISHED;
}
enum cmd_exec_result pfadd_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*PFADD key item [item ...]*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
+ /*PFADD key item [item ...]*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
-
- if(obj->type==OBJ_TYPE_UNDEFINED)
+
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- else if(obj->type!=OBJ_TYPE_HYPERLOGLOG)
+ else if (obj->type != OBJ_TYPE_HYPERLOGLOG)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
- int at_least_one_register_altered=0;
- for(int i=0; i<cmd->argc-2; i++)
+ int at_least_one_register_altered = 0;
+ for (int i = 0; i < cmd->argc - 2; i++)
{
- int ret=0;
- ret=ST_hyperloglog_add(obj->hll, cmd->argv[i+2], sdslen(cmd->argv[i+2]), now);
- if(ret)
- {
- at_least_one_register_altered=1;
- }
+ int ret = 0;
+ ret = ST_hyperloglog_add(obj->hll, cmd->argv[i + 2], sdslen(cmd->argv[i + 2]), now);
+ if (ret)
+ {
+ at_least_one_register_altered = 1;
+ }
}
store_mark_object_as_modified(mod_store, obj);
- *reply=swarmkv_reply_new_integer(at_least_one_register_altered);
+ *reply = swarmkv_reply_new_integer(at_least_one_register_altered);
return FINISHED;
}
enum cmd_exec_result pfcount_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*PFCOUNT key*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ /*PFCOUNT key*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
- if(obj->type==OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- else if(obj->type!=OBJ_TYPE_HYPERLOGLOG)
+ else if (obj->type != OBJ_TYPE_HYPERLOGLOG)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
- long long count=0;
- count=ST_hyperloglog_count(obj->hll, now);
- *reply=swarmkv_reply_new_integer(count);
+ long long count = 0;
+ count = ST_hyperloglog_count(obj->hll, now);
+ *reply = swarmkv_reply_new_integer(count);
return FINISHED;
}
enum cmd_exec_result pfinfo_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*PFINFO key*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ /*PFINFO key*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
- if(obj->type==OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- else if(obj->type!=OBJ_TYPE_HYPERLOGLOG)
+ else if (obj->type != OBJ_TYPE_HYPERLOGLOG)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
struct ST_hyperloglog_info info;
ST_hyperloglog_info(obj->hll, &info);
- int i=0;
- *reply=swarmkv_reply_new_array(6);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Error");
- (*reply)->elements[i++]=swarmkv_reply_new_double(info.error);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Precision");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(info.precision);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("TimeWindowMs");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(info.time_window_ms);
- assert(i==6);
+ int i = 0;
+ *reply = swarmkv_reply_new_array(6);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Error");
+ (*reply)->elements[i++] = swarmkv_reply_new_double(info.error);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Precision");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(info.precision);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("TimeWindowMs");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(info.time_window_ms);
+ assert(i == 6);
return FINISHED;
} \ No newline at end of file
diff --git a/src/t_set.c b/src/t_set.c
index e7d4d4a..404cc7c 100644
--- a/src/t_set.c
+++ b/src/t_set.c
@@ -7,160 +7,159 @@
enum cmd_exec_result sadd_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
-
- obj=store_lookup(mod_store, key);
- if(!obj)
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
return NEED_KEY_ROUTE;
}
-
- if(obj->type==OBJ_TYPE_UNDEFINED)
+
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
uuid_t uuid;
- assert(obj->raw==NULL);
+ assert(obj->raw == NULL);
store_get_uuid(mod_store, uuid);
- obj->set=OR_set_new(uuid);
- obj->type=OBJ_TYPE_SET;
+ obj->set = OR_set_new(uuid);
+ obj->type = OBJ_TYPE_SET;
}
- size_t n_to_add=cmd->argc-2;
- size_t i=0;
- int ret=0;
- int n_added=0;
-
- if(obj->type==OBJ_TYPE_SET)
+ size_t n_to_add = cmd->argc - 2;
+ size_t i = 0;
+ int ret = 0;
+ int n_added = 0;
+
+ if (obj->type == OBJ_TYPE_SET)
{
- for(i=0; i<n_to_add; i++)
+ for (i = 0; i < n_to_add; i++)
{
- ret=OR_set_add(obj->set, cmd->argv[2+i], sdslen(cmd->argv[2+i]));
- if(ret>0) n_added++;
+ ret = OR_set_add(obj->set, cmd->argv[2 + i], sdslen(cmd->argv[2 + i]));
+ if (ret > 0)
+ n_added++;
}
- *reply=swarmkv_reply_new_integer(n_added);
+ *reply = swarmkv_reply_new_integer(n_added);
store_mark_object_as_modified(mod_store, obj);
}
else
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
- }
+ *reply = swarmkv_reply_new_error(error_wrong_type);
+ }
return FINISHED;
-
}
enum cmd_exec_result srem_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
-
- obj=store_lookup(mod_store, key);
- if(!obj)
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
return NEED_KEY_ROUTE;
}
- if(obj->type == OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- if(obj->type!=OBJ_TYPE_SET)
+ if (obj->type != OBJ_TYPE_SET)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
- size_t n_to_rm=cmd->argc-2;
- size_t i=0;
- int ret=0;
- int n_removed=0;
+ size_t n_to_rm = cmd->argc - 2;
+ size_t i = 0;
+ int ret = 0;
+ int n_removed = 0;
- for(i=0; i<n_to_rm; i++)
+ for (i = 0; i < n_to_rm; i++)
{
- ret=OR_set_remove(obj->set, cmd->argv[2+i], sdslen(cmd->argv[2+i]));
- if(ret>0) n_removed++;
+ ret = OR_set_remove(obj->set, cmd->argv[2 + i], sdslen(cmd->argv[2 + i]));
+ if (ret > 0)
+ n_removed++;
}
- *reply=swarmkv_reply_new_integer(n_removed);
+ *reply = swarmkv_reply_new_integer(n_removed);
store_mark_object_as_modified(mod_store, obj);
return FINISHED;
}
enum cmd_exec_result smembers_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
return NEED_KEY_ROUTE;
}
- if(obj->type == OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- if(obj->type!=OBJ_TYPE_SET)
+ if (obj->type != OBJ_TYPE_SET)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
- struct OR_set_member_list *mlist=NULL;
- mlist=OR_set_members(obj->set);
- if(!mlist)
- {
- *reply=swarmkv_reply_new_array(0);//return empty array
+ struct OR_set_member_list *mlist = NULL;
+ mlist = OR_set_members(obj->set);
+ if (!mlist)
+ {
+ *reply = swarmkv_reply_new_array(0); // return empty array
return FINISHED;
}
- size_t i=0;
- *reply=swarmkv_reply_new_array(mlist->n_member);
- for(i=0; i<mlist->n_member; i++)
+ size_t i = 0;
+ *reply = swarmkv_reply_new_array(mlist->n_member);
+ for (i = 0; i < mlist->n_member; i++)
{
- (*reply)->elements[i]=swarmkv_reply_new_string(mlist->members[i], mlist->member_len[i]);
+ (*reply)->elements[i] = swarmkv_reply_new_string(mlist->members[i], mlist->member_len[i]);
}
OR_set_member_list_free(mlist);
return FINISHED;
}
enum cmd_exec_result sismember_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
return NEED_KEY_ROUTE;
}
- if(obj->type == OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- if(obj->type!=OBJ_TYPE_SET)
+ if (obj->type != OBJ_TYPE_SET)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
- int ret=0;
- ret=OR_set_is_member(obj->set, cmd->argv[2], sdslen(cmd->argv[2]));
- *reply=swarmkv_reply_new_integer(ret);
+ int ret = 0;
+ ret = OR_set_is_member(obj->set, cmd->argv[2], sdslen(cmd->argv[2]));
+ *reply = swarmkv_reply_new_integer(ret);
return FINISHED;
}
enum cmd_exec_result scard_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
return NEED_KEY_ROUTE;
}
- if(obj->type == OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- if(obj->type!=OBJ_TYPE_SET)
+ if (obj->type != OBJ_TYPE_SET)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
- int ret=0;
- ret=OR_set_cardinality(obj->set);
- *reply=swarmkv_reply_new_integer(ret);
+ int ret = 0;
+ ret = OR_set_cardinality(obj->set);
+ *reply = swarmkv_reply_new_integer(ret);
return FINISHED;
}
-
-
diff --git a/src/t_string.c b/src/t_string.c
index 1a5f5f5..e63cc18 100644
--- a/src/t_string.c
+++ b/src/t_string.c
@@ -7,140 +7,140 @@
enum cmd_exec_result get_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
- obj=store_lookup(mod_store, key);
- const char *string_val=NULL;
- size_t string_sz=0;
- if(!obj)
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+ obj = store_lookup(mod_store, key);
+ const char *string_val = NULL;
+ size_t string_sz = 0;
+ if (!obj)
{
return NEED_KEY_ROUTE;
}
- if(obj->type == OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
- }
- if(obj->type==OBJ_TYPE_STRING)
+ }
+ if (obj->type == OBJ_TYPE_STRING)
{
LWW_register_get0(obj->string, &string_val, &string_sz);
- *reply=swarmkv_reply_new_string(string_val, string_sz);
+ *reply = swarmkv_reply_new_string(string_val, string_sz);
}
- else if(obj->type==OBJ_TYPE_INTEGER)
+ else if (obj->type == OBJ_TYPE_INTEGER)
{
- long long integer_val=PN_counter_get(obj->counter);
- *reply=swarmkv_reply_new_string_from_integer(integer_val);
+ long long integer_val = PN_counter_get(obj->counter);
+ *reply = swarmkv_reply_new_string_from_integer(integer_val);
}
else
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
}
return FINISHED;
}
enum cmd_exec_result set_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
- const sds value=cmd->argv[2];
-
- char *endptr=NULL;
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+ const sds value = cmd->argv[2];
+
+ char *endptr = NULL;
+
+ long long int_value = -1;
+ int_value = strtol(cmd->argv[2], &endptr, 10);
- long long int_value=-1;
- int_value=strtol(cmd->argv[2], &endptr, 10);
-
- obj=store_lookup(mod_store, key);
- if(!obj)
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
return NEED_KEY_ROUTE;
}
- if(obj->type==OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
uuid_t uuid;
- assert(obj->raw==NULL);
+ assert(obj->raw == NULL);
store_get_uuid(mod_store, uuid);
- if(*endptr=='\0')
+ if (*endptr == '\0')
{
- obj->type=OBJ_TYPE_INTEGER;
- obj->counter=PN_counter_new(uuid);
+ obj->type = OBJ_TYPE_INTEGER;
+ obj->counter = PN_counter_new(uuid);
}
else
{
- obj->type=OBJ_TYPE_STRING;
- obj->string=LWW_register_new(uuid);
+ obj->type = OBJ_TYPE_STRING;
+ obj->string = LWW_register_new(uuid);
}
}
- if(obj->type==OBJ_TYPE_STRING)
+ if (obj->type == OBJ_TYPE_STRING)
{
LWW_register_set(obj->string, value, sdslen(value));
- *reply=swarmkv_reply_new_status("OK");
+ *reply = swarmkv_reply_new_status("OK");
store_mark_object_as_modified(mod_store, obj);
}
- else if(obj->type==OBJ_TYPE_INTEGER)
+ else if (obj->type == OBJ_TYPE_INTEGER)
{
- if(*endptr=='\0')
+ if (*endptr == '\0')
{
- PN_counter_set(obj->counter, int_value);
- *reply=swarmkv_reply_new_status("OK");
- store_mark_object_as_modified(mod_store, obj);
+ PN_counter_set(obj->counter, int_value);
+ *reply = swarmkv_reply_new_status("OK");
+ store_mark_object_as_modified(mod_store, obj);
}
else
{
- *reply=swarmkv_reply_new_error(error_value_not_integer);
+ *reply = swarmkv_reply_new_error(error_value_not_integer);
}
}
else
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
}
return FINISHED;
}
enum cmd_exec_result integer_generic(struct swarmkv_module *mod_store, const sds key, long long increment, struct swarmkv_reply **reply)
{
- struct sobj *obj=NULL;
- long long value=0;
- obj=store_lookup(mod_store, key);
- if(!obj)
+ struct sobj *obj = NULL;
+ long long value = 0;
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
return NEED_KEY_ROUTE;
}
- if(obj->type==OBJ_TYPE_UNDEFINED||obj->type==OBJ_TYPE_INTEGER)
+ if (obj->type == OBJ_TYPE_UNDEFINED || obj->type == OBJ_TYPE_INTEGER)
{
- if(!obj->counter)
+ if (!obj->counter)
{
uuid_t uuid;
store_get_uuid(mod_store, uuid);
- obj->counter=PN_counter_new(uuid);
- obj->type=OBJ_TYPE_INTEGER;
+ obj->counter = PN_counter_new(uuid);
+ obj->type = OBJ_TYPE_INTEGER;
}
- value=PN_counter_incrby(obj->counter, increment);
- *reply=swarmkv_reply_new_integer(value);
+ value = PN_counter_incrby(obj->counter, increment);
+ *reply = swarmkv_reply_new_integer(value);
store_mark_object_as_modified(mod_store, obj);
}
else
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
}
return FINISHED;
}
enum cmd_exec_result incrby_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* INCRBY key increment*/
- long long increment=0;
- char *endptr=NULL;
- increment=strtol(cmd->argv[2], &endptr, 10);
- if(*endptr!='\0')
+ /* INCRBY key increment*/
+ long long increment = 0;
+ char *endptr = NULL;
+ increment = strtol(cmd->argv[2], &endptr, 10);
+ if (*endptr != '\0')
{
- *reply=swarmkv_reply_new_error(error_value_not_integer);
- return FINISHED;
+ *reply = swarmkv_reply_new_error(error_value_not_integer);
+ return FINISHED;
}
return integer_generic(mod_store, cmd->argv[1], increment, reply);
}
enum cmd_exec_result incr_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* INCR key*/
+ /* INCR key*/
return integer_generic(mod_store, cmd->argv[1], 1, reply);
}
enum cmd_exec_result decr_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/* DECR key*/
+ /* DECR key*/
return integer_generic(mod_store, cmd->argv[1], -1, reply);
}
diff --git a/src/t_token_bucket.c b/src/t_token_bucket.c
index 3062222..1d5a72d 100644
--- a/src/t_token_bucket.c
+++ b/src/t_token_bucket.c
@@ -7,21 +7,21 @@
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
-//Unlike string, set and hash, XTCONSUME and XTINFO can only operate on an initialized token bucket.
+// Unlike string, set and hash, XTCONSUME and XTINFO can only operate on an initialized token bucket.
static int get_consume_type(sds s, enum tb_consume_type *consume_type)
{
- if(0==strncasecmp(s, "NORMAL", sdslen(s)))
+ if (0 == strncasecmp(s, "NORMAL", sdslen(s)))
{
- *consume_type=TB_CONSUME_NORMAL;
+ *consume_type = TB_CONSUME_NORMAL;
}
- if(0==strncasecmp(s, "FORCE", sdslen(s)))
+ if (0 == strncasecmp(s, "FORCE", sdslen(s)))
{
- *consume_type=TB_CONSUME_FORCE;
+ *consume_type = TB_CONSUME_FORCE;
}
- else if(0==strncasecmp(s, "FLEXIBLE", sdslen(s)))
+ else if (0 == strncasecmp(s, "FLEXIBLE", sdslen(s)))
{
- *consume_type=TB_CONSUME_FLEXIBLE;
+ *consume_type = TB_CONSUME_FLEXIBLE;
}
else
{
@@ -31,311 +31,311 @@ static int get_consume_type(sds s, enum tb_consume_type *consume_type)
}
enum cmd_exec_result tcfg_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*TCFG key rate capacity [PD seconds]*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
-
- char *endptr=NULL;
+ /*TCFG key rate capacity [PD seconds]*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
- long long rate=0, capacity=0, period=1;
- rate=strtol(cmd->argv[2], &endptr, 10);
- if(*endptr!='\0' || rate<0)
+ char *endptr = NULL;
+
+ long long rate = 0, capacity = 0, period = 1;
+ rate = strtol(cmd->argv[2], &endptr, 10);
+ if (*endptr != '\0' || rate < 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
- return FINISHED;
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
+ return FINISHED;
}
- capacity=strtol(cmd->argv[3], &endptr, 10);
- if(*endptr!='\0' || capacity<0)
+ capacity = strtol(cmd->argv[3], &endptr, 10);
+ if (*endptr != '\0' || capacity < 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[3]);
- return FINISHED;
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[3]);
+ return FINISHED;
}
- if(cmd->argc==6)
+ if (cmd->argc == 6)
{
- if(strcasecmp(cmd->argv[4], "PD")!=0)
+ if (strcasecmp(cmd->argv[4], "PD") != 0)
{
- *reply=swarmkv_reply_new_error(error_arg_string_should_be, cmd->argv[5], "PD");
+ *reply = swarmkv_reply_new_error(error_arg_string_should_be, cmd->argv[5], "PD");
return FINISHED;
}
- period=strtol(cmd->argv[5], &endptr, 10);
- if(*endptr!='\0' || period<0)
+ period = strtol(cmd->argv[5], &endptr, 10);
+ if (*endptr != '\0' || period < 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[5]);
- return FINISHED;
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[5]);
+ return FINISHED;
}
}
- obj=store_lookup(mod_store, key);
- if(!obj)
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
-
- if(obj->type==OBJ_TYPE_UNDEFINED)
+
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
uuid_t uuid;
- assert(obj->raw==NULL);
+ assert(obj->raw == NULL);
store_get_uuid(mod_store, uuid);
- obj->bucket=OC_token_bucket_new(uuid, now, rate, period, capacity);
- obj->type=OBJ_TYPE_TOKEN_BUCKET;
- *reply=swarmkv_reply_new_status("OK");
+ obj->bucket = OC_token_bucket_new(uuid, now, rate, period, capacity);
+ obj->type = OBJ_TYPE_TOKEN_BUCKET;
+ *reply = swarmkv_reply_new_status("OK");
}
- else if(obj->type==OBJ_TYPE_TOKEN_BUCKET)
+ else if (obj->type == OBJ_TYPE_TOKEN_BUCKET)
{
OC_token_bucket_configure(obj->bucket, now, rate, period, capacity);
store_mark_object_as_modified(mod_store, obj);
- *reply=swarmkv_reply_new_status("OK");
+ *reply = swarmkv_reply_new_status("OK");
}
else
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
- }
+ *reply = swarmkv_reply_new_error(error_wrong_type);
+ }
return FINISHED;
}
enum cmd_exec_result tinfo_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*TINFO key*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
-
- obj=store_lookup(mod_store, key);
- if(!obj)
+ /*TINFO key*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
- if(obj->type==OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- if(obj->type!=OBJ_TYPE_TOKEN_BUCKET)
+ if (obj->type != OBJ_TYPE_TOKEN_BUCKET)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
struct timeval now;
gettimeofday(&now, NULL);
-
-
+
struct OC_token_bucket_info oc_info;
memset(&oc_info, 0, sizeof(oc_info));
OC_token_bucket_info(obj->bucket, now, &oc_info);
- int i=0;
- *reply=swarmkv_reply_new_array(14);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Rate");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(oc_info.rate);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Period");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(oc_info.period);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Capacity");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(oc_info.capacity);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Consumed");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(oc_info.consumed);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Refilled");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(oc_info.refilled);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Available");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(oc_info.available);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("LastConsumeMs");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(oc_info.last_consume_ms);
- assert(i==14);
+ int i = 0;
+ *reply = swarmkv_reply_new_array(14);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Rate");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(oc_info.rate);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Period");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(oc_info.period);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Capacity");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(oc_info.capacity);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Consumed");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(oc_info.consumed);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Refilled");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(oc_info.refilled);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Available");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(oc_info.available);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("LastConsumeMs");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(oc_info.last_consume_ms);
+ assert(i == 14);
return FINISHED;
}
enum cmd_exec_result tconsume_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*TCONSUME key tokens [NORMAL|FORCE|FLEXIBLE]*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ /*TCONSUME key tokens [NORMAL|FORCE|FLEXIBLE]*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
- if(obj->type==OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- long long request=0, allocated=0;
- char *endptr=NULL;
- request=strtol(cmd->argv[2], &endptr, 10);
- if(*endptr!='\0' || request<0)
+ long long request = 0, allocated = 0;
+ char *endptr = NULL;
+ request = strtol(cmd->argv[2], &endptr, 10);
+ if (*endptr != '\0' || request < 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
return FINISHED;
}
- enum tb_consume_type consume_type=TB_CONSUME_NORMAL;
- if(cmd->argc>3)
+ enum tb_consume_type consume_type = TB_CONSUME_NORMAL;
+ if (cmd->argc > 3)
{
- if(0>get_consume_type(cmd->argv[3], &consume_type))
+ if (0 > get_consume_type(cmd->argv[3], &consume_type))
{
- *reply=swarmkv_reply_new_error(error_arg_string_should_be, cmd->argv[3], "NORMAL|FORCE|FLEXIBLE");
+ *reply = swarmkv_reply_new_error(error_arg_string_should_be, cmd->argv[3], "NORMAL|FORCE|FLEXIBLE");
return FINISHED;
}
}
- if(obj->type!=OBJ_TYPE_TOKEN_BUCKET)
+ if (obj->type != OBJ_TYPE_TOKEN_BUCKET)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
struct timeval now;
gettimeofday(&now, NULL);
- allocated=OC_token_bucket_consume(obj->bucket, now, consume_type, request);
- *reply=swarmkv_reply_new_integer(allocated);
+ allocated = OC_token_bucket_consume(obj->bucket, now, consume_type, request);
+ *reply = swarmkv_reply_new_integer(allocated);
store_mark_object_as_modified(mod_store, obj);
return FINISHED;
}
-bool is_power_of_2(long long num)
+bool is_power_of_2(long long num)
{
- if (num > 0 && (num & (num - 1)) == 0) {
- return true;
- }
- return false;
+ if (num > 0 && (num & (num - 1)) == 0)
+ {
+ return true;
+ }
+ return false;
}
enum cmd_exec_result ftcfg_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*FTCFG key rate capacity divisor [PERIOD seconds]*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
-
- char *endptr=NULL;
+ /*FTCFG key rate capacity divisor [PERIOD seconds]*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
- long long rate=0, capacity=0, divisor=0, period=1;
- rate=strtol(cmd->argv[2], &endptr, 10);
- if(*endptr!='\0' || rate<0)
+ char *endptr = NULL;
+
+ long long rate = 0, capacity = 0, divisor = 0, period = 1;
+ rate = strtol(cmd->argv[2], &endptr, 10);
+ if (*endptr != '\0' || rate < 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
- return FINISHED;
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
+ return FINISHED;
}
- capacity=strtol(cmd->argv[3], &endptr, 10);
- if(*endptr!='\0' || capacity<0)
+ capacity = strtol(cmd->argv[3], &endptr, 10);
+ if (*endptr != '\0' || capacity < 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[3]);
- return FINISHED;
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[3]);
+ return FINISHED;
}
- divisor=strtol(cmd->argv[4], &endptr, 10);
- if(*endptr!='\0' || !is_power_of_2(divisor))
+ divisor = strtol(cmd->argv[4], &endptr, 10);
+ if (*endptr != '\0' || !is_power_of_2(divisor))
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[4]);
- return FINISHED;
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[4]);
+ return FINISHED;
}
- if(cmd->argc==7)
+ if (cmd->argc == 7)
{
- if(strcasecmp(cmd->argv[5], "PD")!=0)
+ if (strcasecmp(cmd->argv[5], "PD") != 0)
{
- *reply=swarmkv_reply_new_error(error_arg_string_should_be, cmd->argv[5], "PD");
+ *reply = swarmkv_reply_new_error(error_arg_string_should_be, cmd->argv[5], "PD");
return FINISHED;
}
- period=strtol(cmd->argv[6], &endptr, 10);
- if(*endptr!='\0' || period<0)
+ period = strtol(cmd->argv[6], &endptr, 10);
+ if (*endptr != '\0' || period < 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[6]);
- return FINISHED;
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[6]);
+ return FINISHED;
}
}
- obj=store_lookup(mod_store, key);
- if(!obj)
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
-
- if(obj->type==OBJ_TYPE_UNDEFINED)
+
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
uuid_t uuid;
- assert(obj->raw==NULL);
+ assert(obj->raw == NULL);
store_get_uuid(mod_store, uuid);
-
- obj->type=OBJ_TYPE_FAIR_TOKEN_BUCKET;
- obj->ftb=fair_token_bucket_new(uuid, now, rate, period, capacity, divisor);
- *reply=swarmkv_reply_new_status("OK");
+
+ obj->type = OBJ_TYPE_FAIR_TOKEN_BUCKET;
+ obj->ftb = fair_token_bucket_new(uuid, now, rate, period, capacity, divisor);
+ *reply = swarmkv_reply_new_status("OK");
}
- else if(obj->type==OBJ_TYPE_FAIR_TOKEN_BUCKET)
+ else if (obj->type == OBJ_TYPE_FAIR_TOKEN_BUCKET)
{
fair_token_bucket_configure(obj->ftb, now, rate, period, capacity, divisor);
store_mark_object_as_modified(mod_store, obj);
- *reply=swarmkv_reply_new_status("OK");
+ *reply = swarmkv_reply_new_status("OK");
}
else
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
- }
+ *reply = swarmkv_reply_new_error(error_wrong_type);
+ }
return FINISHED;
}
enum cmd_exec_result ftconsume_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*FTCONSUME key member weight tokens [NORMAL|FORCE|FLEXIBLE]*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
- const sds member=cmd->argv[2];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ /*FTCONSUME key member weight tokens [NORMAL|FORCE|FLEXIBLE]*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+ const sds member = cmd->argv[2];
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
- if(obj->type==OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- long long request=0, allocated=0;
- char *endptr=NULL;
- request=strtol(cmd->argv[4], &endptr, 10);
- if(*endptr!='\0' || request<0)
+ long long request = 0, allocated = 0;
+ char *endptr = NULL;
+ request = strtol(cmd->argv[4], &endptr, 10);
+ if (*endptr != '\0' || request < 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[4]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[4]);
return FINISHED;
}
- long long weight=0;
- weight=strtol(cmd->argv[3], &endptr, 10);
- if(*endptr!='\0' || weight<1 || weight>FAIR_TB_WEIGHT_MAX)
+ long long weight = 0;
+ weight = strtol(cmd->argv[3], &endptr, 10);
+ if (*endptr != '\0' || weight < 1 || weight > FAIR_TB_WEIGHT_MAX)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[3]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[3]);
return FINISHED;
}
- if(obj->type!=OBJ_TYPE_FAIR_TOKEN_BUCKET)
+ if (obj->type != OBJ_TYPE_FAIR_TOKEN_BUCKET)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
- enum tb_consume_type consume_type=TB_CONSUME_NORMAL;
- if(cmd->argc>5)
+ enum tb_consume_type consume_type = TB_CONSUME_NORMAL;
+ if (cmd->argc > 5)
{
- if(0>get_consume_type(cmd->argv[5], &consume_type))
+ if (0 > get_consume_type(cmd->argv[5], &consume_type))
{
- *reply=swarmkv_reply_new_error(error_arg_string_should_be, cmd->argv[4], "NORMAL|FORCE|FLEXIBLE");
+ *reply = swarmkv_reply_new_error(error_arg_string_should_be, cmd->argv[4], "NORMAL|FORCE|FLEXIBLE");
return FINISHED;
}
}
struct timeval now;
gettimeofday(&now, NULL);
- allocated=fair_token_bucket_consume(obj->ftb, now, member, sdslen(member), weight, consume_type, request);
+ allocated = fair_token_bucket_consume(obj->ftb, now, member, sdslen(member), weight, consume_type, request);
- *reply=swarmkv_reply_new_integer(allocated);
+ *reply = swarmkv_reply_new_integer(allocated);
store_mark_object_as_modified(mod_store, obj);
return FINISHED;
}
enum cmd_exec_result ftinfo_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*FTINFO key*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
-
- obj=store_lookup(mod_store, key);
- if(!obj)
+ /*FTINFO key*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
- if(obj->type==OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- if(obj->type!=OBJ_TYPE_FAIR_TOKEN_BUCKET)
+ if (obj->type != OBJ_TYPE_FAIR_TOKEN_BUCKET)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
struct timeval now;
@@ -344,167 +344,167 @@ enum cmd_exec_result ftinfo_command(struct swarmkv_module *mod_store, const stru
struct fair_token_bucket_info ftb_info;
memset(&ftb_info, 0, sizeof(ftb_info));
fair_token_bucket_info(obj->ftb, now, &ftb_info);
-
- int i=0;
- *reply=swarmkv_reply_new_array(18);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Refill");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(ftb_info.bucket_info.rate);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Period");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(ftb_info.bucket_info.period);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Capacity");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(ftb_info.bucket_info.capacity);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Consumed");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(ftb_info.bucket_info.consumed);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Refilled");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(ftb_info.bucket_info.refilled);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Available");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(ftb_info.bucket_info.available);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("LastConsumeMs");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(ftb_info.bucket_info.last_consume_ms);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Divisor");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(ftb_info.divisor);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("ActiveMembers");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(ftb_info.active_key_number);
- assert(i==18);
+
+ int i = 0;
+ *reply = swarmkv_reply_new_array(18);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Refill");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(ftb_info.bucket_info.rate);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Period");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(ftb_info.bucket_info.period);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Capacity");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(ftb_info.bucket_info.capacity);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Consumed");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(ftb_info.bucket_info.consumed);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Refilled");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(ftb_info.bucket_info.refilled);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Available");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(ftb_info.bucket_info.available);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("LastConsumeMs");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(ftb_info.bucket_info.last_consume_ms);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Divisor");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(ftb_info.divisor);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("ActiveMembers");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(ftb_info.active_key_number);
+ assert(i == 18);
return FINISHED;
}
enum cmd_exec_result btcfg_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*BTCFG key rate capacity buckets [PD seconds]*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
-
- char *endptr=NULL;
+ /*BTCFG key rate capacity buckets [PD seconds]*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+
+ char *endptr = NULL;
- long long rate=0, capacity=0, buckets=0, period=1;
- rate=strtol(cmd->argv[2], &endptr, 10);
- if(*endptr!='\0' || rate<0)
+ long long rate = 0, capacity = 0, buckets = 0, period = 1;
+ rate = strtol(cmd->argv[2], &endptr, 10);
+ if (*endptr != '\0' || rate < 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
- return FINISHED;
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[2]);
+ return FINISHED;
}
- capacity=strtol(cmd->argv[3], &endptr, 10);
- if(*endptr!='\0' || capacity<0)
+ capacity = strtol(cmd->argv[3], &endptr, 10);
+ if (*endptr != '\0' || capacity < 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[3]);
- return FINISHED;
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[3]);
+ return FINISHED;
}
- buckets=strtol(cmd->argv[4], &endptr, 10);
- if(*endptr!='\0' || !is_power_of_2(buckets))
+ buckets = strtol(cmd->argv[4], &endptr, 10);
+ if (*endptr != '\0' || !is_power_of_2(buckets))
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[4]);
- return FINISHED;
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[4]);
+ return FINISHED;
}
- if(cmd->argc==7)
+ if (cmd->argc == 7)
{
- if(strcasecmp(cmd->argv[5], "PD")!=0)
+ if (strcasecmp(cmd->argv[5], "PD") != 0)
{
- *reply=swarmkv_reply_new_error(error_arg_string_should_be, cmd->argv[5], "PD");
+ *reply = swarmkv_reply_new_error(error_arg_string_should_be, cmd->argv[5], "PD");
return FINISHED;
}
- period=strtol(cmd->argv[6], &endptr, 10);
- if(*endptr!='\0' || period<0)
+ period = strtol(cmd->argv[6], &endptr, 10);
+ if (*endptr != '\0' || period < 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[6]);
- return FINISHED;
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[6]);
+ return FINISHED;
}
}
- obj=store_lookup(mod_store, key);
- if(!obj)
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
struct timeval now;
gettimeofday(&now, NULL);
-
- if(obj->type==OBJ_TYPE_UNDEFINED)
+
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
uuid_t uuid;
- assert(obj->raw==NULL);
+ assert(obj->raw == NULL);
store_get_uuid(mod_store, uuid);
-
- obj->type=OBJ_TYPE_BULK_TOKEN_BUCKET;
- obj->btb=bulk_token_bucket_new(uuid, now, rate, period, capacity, buckets);
- *reply=swarmkv_reply_new_status("OK");
+
+ obj->type = OBJ_TYPE_BULK_TOKEN_BUCKET;
+ obj->btb = bulk_token_bucket_new(uuid, now, rate, period, capacity, buckets);
+ *reply = swarmkv_reply_new_status("OK");
}
- else if(obj->type==OBJ_TYPE_BULK_TOKEN_BUCKET)
+ else if (obj->type == OBJ_TYPE_BULK_TOKEN_BUCKET)
{
bulk_token_bucket_configure(obj->btb, now, rate, period, capacity, buckets);
store_mark_object_as_modified(mod_store, obj);
- *reply=swarmkv_reply_new_status("OK");
+ *reply = swarmkv_reply_new_status("OK");
}
else
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
- }
+ *reply = swarmkv_reply_new_error(error_wrong_type);
+ }
return FINISHED;
}
enum cmd_exec_result btconsume_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*BTCONSUME key member tokens [NORMAL|FORCE|FLEXIBLE]*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
- const sds member=cmd->argv[2];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ /*BTCONSUME key member tokens [NORMAL|FORCE|FLEXIBLE]*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+ const sds member = cmd->argv[2];
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
- if(obj->type==OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- long long request=0, allocated=0;
- char *endptr=NULL;
- request=strtol(cmd->argv[3], &endptr, 10);
- if(*endptr!='\0' || request<0)
+ long long request = 0, allocated = 0;
+ char *endptr = NULL;
+ request = strtol(cmd->argv[3], &endptr, 10);
+ if (*endptr != '\0' || request < 0)
{
- *reply=swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[3]);
+ *reply = swarmkv_reply_new_error(error_arg_not_valid_integer, cmd->argv[3]);
return FINISHED;
}
- enum tb_consume_type consume_type=TB_CONSUME_NORMAL;
- if(cmd->argc>4)
+ enum tb_consume_type consume_type = TB_CONSUME_NORMAL;
+ if (cmd->argc > 4)
{
- if(0>get_consume_type(cmd->argv[4], &consume_type))
+ if (0 > get_consume_type(cmd->argv[4], &consume_type))
{
- *reply=swarmkv_reply_new_error(error_arg_string_should_be, cmd->argv[4], "NORMAL|FORCE|FLEXIBLE");
+ *reply = swarmkv_reply_new_error(error_arg_string_should_be, cmd->argv[4], "NORMAL|FORCE|FLEXIBLE");
return FINISHED;
}
}
- if(obj->type!=OBJ_TYPE_BULK_TOKEN_BUCKET)
+ if (obj->type != OBJ_TYPE_BULK_TOKEN_BUCKET)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
struct timeval now;
gettimeofday(&now, NULL);
- allocated=bulk_token_bucket_consume(obj->btb, now, member, sdslen(member), consume_type, request);
+ allocated = bulk_token_bucket_consume(obj->btb, now, member, sdslen(member), consume_type, request);
- *reply=swarmkv_reply_new_integer(allocated);
+ *reply = swarmkv_reply_new_integer(allocated);
store_mark_object_as_modified(mod_store, obj);
return FINISHED;
}
enum cmd_exec_result btinfo_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*BTINFO key*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
-
- obj=store_lookup(mod_store, key);
- if(!obj)
+ /*BTINFO key*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
- if(obj->type==OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- if(obj->type!=OBJ_TYPE_BULK_TOKEN_BUCKET)
+ if (obj->type != OBJ_TYPE_BULK_TOKEN_BUCKET)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
struct timeval now;
@@ -514,44 +514,44 @@ enum cmd_exec_result btinfo_command(struct swarmkv_module *mod_store, const stru
memset(&btb_info, 0, sizeof(btb_info));
bulk_token_bucket_info(obj->btb, now, &btb_info);
- int i=0;
- *reply=swarmkv_reply_new_array(14);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Rate");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(btb_info.rate);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Period");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(btb_info.period);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Capacity");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(btb_info.capacity);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("InitialBuckets");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(btb_info.initial_bucket_number);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Buckets");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(btb_info.bucket_number);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("ActiveBuckets");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(btb_info.active_bucket_number);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("MaxReplicas");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(btb_info.max_replicas);
- assert(i==14);
+ int i = 0;
+ *reply = swarmkv_reply_new_array(14);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Rate");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(btb_info.rate);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Period");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(btb_info.period);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Capacity");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(btb_info.capacity);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("InitialBuckets");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(btb_info.initial_bucket_number);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Buckets");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(btb_info.bucket_number);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("ActiveBuckets");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(btb_info.active_bucket_number);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("MaxReplicas");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(btb_info.max_replicas);
+ assert(i == 14);
return FINISHED;
}
enum cmd_exec_result btquery_command(struct swarmkv_module *mod_store, const struct swarmkv_cmd *cmd, struct swarmkv_reply **reply)
{
-/*BTQUERY key member*/
- struct sobj *obj=NULL;
- const sds key=cmd->argv[1];
- const sds member=cmd->argv[2];
+ /*BTQUERY key member*/
+ struct sobj *obj = NULL;
+ const sds key = cmd->argv[1];
+ const sds member = cmd->argv[2];
- obj=store_lookup(mod_store, key);
- if(!obj)
+ obj = store_lookup(mod_store, key);
+ if (!obj)
{
- return NEED_KEY_ROUTE;
+ return NEED_KEY_ROUTE;
}
- if(obj->type==OBJ_TYPE_UNDEFINED)
+ if (obj->type == OBJ_TYPE_UNDEFINED)
{
return handle_undefined_object(obj, reply);
}
- if(obj->type!=OBJ_TYPE_BULK_TOKEN_BUCKET)
+ if (obj->type != OBJ_TYPE_BULK_TOKEN_BUCKET)
{
- *reply=swarmkv_reply_new_error(error_wrong_type);
+ *reply = swarmkv_reply_new_error(error_wrong_type);
return FINISHED;
}
struct timeval now;
@@ -561,20 +561,20 @@ enum cmd_exec_result btquery_command(struct swarmkv_module *mod_store, const str
memset(&key_info, 0, sizeof(key_info));
bulk_token_bucket_query(obj->btb, now, member, sdslen(member), &key_info);
- int i=0;
- *reply=swarmkv_reply_new_array(12);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Consumed");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(key_info.consumed);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Refilled");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(key_info.refilled);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Available");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(key_info.available);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Replicas");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(key_info.number_of_replica);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("LastConsumeMs");
- (*reply)->elements[i++]=swarmkv_reply_new_integer(key_info.last_consume_ms);
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("Hash");
- (*reply)->elements[i++]=swarmkv_reply_new_string_fmt("%llu.%llu", key_info.hash_low64, key_info.hash_high64);
- assert(i==12);
+ int i = 0;
+ *reply = swarmkv_reply_new_array(12);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Consumed");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(key_info.consumed);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Refilled");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(key_info.refilled);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Available");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(key_info.available);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Replicas");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(key_info.number_of_replica);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("LastConsumeMs");
+ (*reply)->elements[i++] = swarmkv_reply_new_integer(key_info.last_consume_ms);
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("Hash");
+ (*reply)->elements[i++] = swarmkv_reply_new_string_fmt("%llu.%llu", key_info.hash_low64, key_info.hash_high64);
+ assert(i == 12);
return FINISHED;
} \ No newline at end of file
diff --git a/test/swarmkv_gtest.cpp b/test/swarmkv_gtest.cpp
index 3fad3ca..7dae39e 100644
--- a/test/swarmkv_gtest.cpp
+++ b/test/swarmkv_gtest.cpp
@@ -975,6 +975,7 @@ TEST_F(SwarmkvBasicTest, HashTags)
swarmkv_reply_free(reply);
}
}
+
class SwarmkvTwoNodes : public testing::Test
{
@@ -1005,6 +1006,7 @@ protected:
swarmkv_options_set_worker_thread_number(opts[i], 2);
swarmkv_options_set_caller_thread_number(opts[i], 1);
swarmkv_options_set_batch_sync_enabled(opts[i], 1);
+ swarmkv_options_set_network_compression_enabled(opts[i], i%2);
tmp_db[i]=swarmkv_open(opts[i], cluster_name, &err);
if(err)
{
@@ -2050,6 +2052,107 @@ TEST_F(SwarmkvTwoNodes, Monitor)
swarmkv_reply_free(reply);
}
}
+TEST_F(SwarmkvTwoNodes, Management)
+{
+ struct swarmkv *db1=SwarmkvTwoNodes::db1;
+ struct swarmkv_reply *reply=NULL;
+
+ reply=swarmkv_command(db1, "info");
+ EXPECT_EQ(reply->type, SWARMKV_REPLY_STATUS);
+ swarmkv_reply_free(reply);
+
+ reply=swarmkv_command(db1, "info Store");
+ EXPECT_EQ(reply->type, SWARMKV_REPLY_STATUS);
+ swarmkv_reply_free(reply);
+
+ reply=swarmkv_command(db1, "command list");
+ ASSERT_EQ(reply->type, SWARMKV_REPLY_ARRAY);
+ EXPECT_GE(reply->n_element, 50);
+ for(size_t i=0; i<reply->n_element; i++)
+ {
+ EXPECT_EQ(reply->elements[i]->type, SWARMKV_REPLY_STRING);
+ EXPECT_GE(strlen(reply->elements[i]->str), 2);
+ }
+ swarmkv_reply_free(reply);
+}
+TEST_F(SwarmkvTwoNodes, Ping)
+{
+ struct swarmkv *db1=SwarmkvTwoNodes::db1;
+ struct swarmkv_reply *reply=NULL;
+ char db1_address[128], db2_address[128];
+ snprintf(db1_address, sizeof(db1_address), "127.0.0.1:%d", TWO_NODES_TEST_CLUSTER_PORT);
+ snprintf(db2_address, sizeof(db2_address), "127.0.0.1:%d", TWO_NODES_TEST_CLUSTER_PORT+1);
+ reply=swarmkv_command_on(db1, db1_address, "ping %s", db1_address);
+ EXPECT_EQ(reply->type, SWARMKV_REPLY_STRING);
+ swarmkv_reply_free(reply);
+
+ reply=swarmkv_command_on(db1, db1_address, "ping %s", db2_address);
+ EXPECT_EQ(reply->type, SWARMKV_REPLY_STRING);
+ swarmkv_reply_free(reply);
+}
+TEST_F(SwarmkvTwoNodes, Latency)
+{
+ struct swarmkv *db1=SwarmkvTwoNodes::db1;
+ struct swarmkv_reply *reply=NULL;
+
+ reply=swarmkv_command(db1, "latency reset command");
+ EXPECT_EQ(reply->type, SWARMKV_REPLY_STATUS);
+ swarmkv_reply_free(reply);
+
+ reply=swarmkv_command(db1, "latency reset peer");
+ EXPECT_EQ(reply->type, SWARMKV_REPLY_STATUS);
+ swarmkv_reply_free(reply);
+
+ reply=swarmkv_command(db1, "latency reset event");
+ EXPECT_EQ(reply->type, SWARMKV_REPLY_STATUS);
+ swarmkv_reply_free(reply);
+
+ reply=swarmkv_command(db1, "latency reset");
+ EXPECT_EQ(reply->type, SWARMKV_REPLY_STATUS);
+ swarmkv_reply_free(reply);
+
+ const char *key="6aoX1f94XXIUJYH";
+ reply=swarmkv_command(db1, "set %s abc", key);
+ EXPECT_EQ(reply->type, SWARMKV_REPLY_STATUS);
+ swarmkv_reply_free(reply);
+
+ //Read the count of 'SET' command
+ long long exec_count=0;
+ char ignore[128];
+
+ reply=swarmkv_command(db1, "latency command set");
+ ASSERT_EQ(reply->type, SWARMKV_REPLY_ARRAY);
+ EXPECT_EQ(reply->n_element, 2);
+ EXPECT_EQ(reply->elements[1]->type, SWARMKV_REPLY_STATUS);
+
+ sscanf(reply->elements[1]->str, "| %[^|] | %lld", ignore, &exec_count);
+ EXPECT_EQ(exec_count, 2);
+ swarmkv_reply_free(reply);
+
+ reply=swarmkv_command(db1, "latency reset");
+ EXPECT_EQ(reply->type, SWARMKV_REPLY_STATUS);
+ swarmkv_reply_free(reply);
+
+ //Excute count is reseted, should be 0 now.
+ reply=swarmkv_command(db1, "latency command set");
+ ASSERT_EQ(reply->type, SWARMKV_REPLY_ARRAY);
+ EXPECT_EQ(reply->n_element, 2);
+ EXPECT_EQ(reply->elements[1]->type, SWARMKV_REPLY_STATUS);
+ sscanf(reply->elements[1]->str, "| %[^|] | %lld", ignore, &exec_count);
+ EXPECT_EQ(exec_count, 0);
+ swarmkv_reply_free(reply);
+
+ char db2_address[128];
+ snprintf(db2_address, sizeof(db2_address), "127.0.0.1:%d", TWO_NODES_TEST_CLUSTER_PORT+1);
+ reply=swarmkv_command_on(db1, db2_address, "get %s", key);
+ EXPECT_EQ(reply->type, SWARMKV_REPLY_STRING);
+ swarmkv_reply_free(reply);
+
+ reply=swarmkv_command(db1, "latency peer");
+ EXPECT_EQ(reply->type, SWARMKV_REPLY_ARRAY);
+ swarmkv_reply_free(reply);
+ sleep(3500);
+}
TEST_F(SwarmkvTwoNodes, Wait)
{
return;
@@ -2283,6 +2386,7 @@ TEST_F(SwarmkvNNodes, TypeTokenBucket)
}
int main(int argc, char ** argv)
{
+ printf("If see valgrind memory leak waring: 'local_caller_on_success->blocking_query_cb->swarmkv_reply_dup', DON'T WORRY, it's because gtest's ASSERT_EQ interrupts swarmkv_reply_free\n");
int ret=0;
g_current_thread_id=syscall(SYS_gettid);
::testing::InitGoogleTest(&argc, argv);