diff options
| author | 郑超 <[email protected]> | 2024-06-25 08:16:37 +0000 |
|---|---|---|
| committer | 郑超 <[email protected]> | 2024-06-25 08:16:37 +0000 |
| commit | 19df9685b1e1ae0360c6859626e123dbe863a897 (patch) | |
| tree | 85cfc36ef794e079966fc089f4b7fa09821084b0 /src | |
| parent | 4fab21dfa937755238534189755b1c8899bf71a2 (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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/swarmkv.c | 2201 | ||||
| -rw-r--r-- | src/swarmkv_api.c | 506 | ||||
| -rw-r--r-- | src/swarmkv_cmd_spec.c | 202 | ||||
| -rw-r--r-- | src/swarmkv_cmd_spec.h | 14 | ||||
| -rw-r--r-- | src/swarmkv_common.c | 842 | ||||
| -rw-r--r-- | src/swarmkv_common.h | 1 | ||||
| -rw-r--r-- | src/swarmkv_core.h | 6 | ||||
| -rw-r--r-- | src/swarmkv_keyspace.c | 1633 | ||||
| -rw-r--r-- | src/swarmkv_mesh.c | 160 | ||||
| -rw-r--r-- | src/swarmkv_mesh.h | 4 | ||||
| -rw-r--r-- | src/swarmkv_message.c | 326 | ||||
| -rw-r--r-- | src/swarmkv_message.h | 30 | ||||
| -rw-r--r-- | src/swarmkv_monitor.c | 509 | ||||
| -rw-r--r-- | src/swarmkv_monitor.h | 2 | ||||
| -rw-r--r-- | src/swarmkv_net.c | 698 | ||||
| -rw-r--r-- | src/swarmkv_net.h | 8 | ||||
| -rw-r--r-- | src/swarmkv_rpc.c | 92 | ||||
| -rw-r--r-- | src/swarmkv_store.c | 1025 | ||||
| -rw-r--r-- | src/swarmkv_sync.c | 78 | ||||
| -rw-r--r-- | src/swarmkv_utils.c | 176 | ||||
| -rw-r--r-- | src/t_bloom_filter.c | 236 | ||||
| -rw-r--r-- | src/t_cms.c | 350 | ||||
| -rw-r--r-- | src/t_hash.c | 362 | ||||
| -rw-r--r-- | src/t_hyperloglog.c | 147 | ||||
| -rw-r--r-- | src/t_set.c | 153 | ||||
| -rw-r--r-- | src/t_string.c | 120 | ||||
| -rw-r--r-- | src/t_token_bucket.c | 606 |
28 files changed, 5305 insertions, 5184 deletions
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 |
