void server_deinit(struct array *server) { uint32_t i, nserver; for (i = 0, nserver = array_n(server); i < nserver; i++) { struct server *s; s = array_pop(server); ASSERT(TAILQ_EMPTY(&s->s_conn_q) && s->ns_conn_q == 0); } array_deinit(server); }
void ffi_replicaset_deinit(struct replicaset *rs) { int i; for (i = 0; i < NC_MAXTAGNUM; i++) { uint32_t n = array_n(&rs->tagged_servers[i]); while (n--) { array_pop(&rs->tagged_servers[i]); } } rs->master = NULL; }
void dnode_peer_deinit(struct array *nodes) { uint32_t i, nnode; for (i = 0, nnode = array_n(nodes); i < nnode; i++) { struct server *s; s = array_pop(nodes); ASSERT(TAILQ_EMPTY(&s->s_conn_q) && s->ns_conn_q == 0); } array_deinit(nodes); }
/* * Returns the entry that has been removed, if any. */ Array_item *BX_remove_from_array (Array *array, char *name) { int count, location = 0; if (array->max) { find_array_item(array, name, &count, &location); if (count >= 0) return NULL; return array_pop(array, location); } return NULL; /* Cant delete whats not there */ }
Array_item *remove_from_array (Array *array, char *name) { int count, location = 0; if (array->max) { find_array_item(array, name, &count, &location); if (count >= 0) return (void *) 0 ; return array_pop(array, location); } return (void *) 0 ; }
static void stats_server_unmap(struct array *stats_server) { uint32_t i, nserver; nserver = array_n(stats_server); for (i = 0; i < nserver; i++) { struct stats_server *sts = array_pop(stats_server); stats_metric_deinit(&sts->metric); } array_deinit(stats_server); log_debug(LOG_VVVERB, "unmap %"PRIu32" stats servers", nserver); }
void conf_destroy(struct conf *cf) { while (array_n(&cf->arg) != 0) { conf_pop_scalar(cf); } array_deinit(&cf->arg); while (array_n(&cf->pool) != 0) { conf_pool_deinit(array_pop(&cf->pool)); } array_deinit(&cf->pool); nc_free(cf); }
static void conf_pool_deinit(struct conf_pool *cp) { string_deinit(&cp->name); string_deinit(&cp->listen.pname); string_deinit(&cp->listen.name); if (cp->redis_auth.len > 0) { string_deinit(&cp->redis_auth); } while (array_n(&cp->groups) != 0) { string_deinit(array_pop(&cp->groups)); } array_deinit(&cp->groups); while (array_n(&cp->sentinels) != 0) { conf_server_deinit(array_pop(&cp->sentinels)); } array_deinit(&cp->sentinels); log_debug(LOG_VVERB, "deinit conf pool %p", cp); }
static void conf_pool_deinit(struct conf_pool *cp) { string_deinit(&cp->name); string_deinit(&cp->listen.pname); string_deinit(&cp->listen.name); while (array_n(&cp->server) != 0) { conf_server_deinit(array_pop(&cp->server)); } array_deinit(&cp->server); log_debug(LOG_VVERB, "deinit conf pool %p", cp); }
static void stats_pool_unmap(struct array *stats_pool) { uint32_t i, npool; npool = array_n(stats_pool); for (i = 0; i < npool; i++) { struct stats_pool *stp = array_pop(stats_pool); stats_metric_deinit(&stp->metric); stats_server_unmap(&stp->server); } array_deinit(stats_pool); log_debug(LOG_VVVERB, "unmap %"PRIu32" stats pool", npool); }
void test_push_pop() { int i; for (i = 0; i < 100; i++) { int *element = array_new(array); *element = i * 333; array_push(array, element); } mu_assert(array->max == 151, "Wrong max size"); for (i = 99; i >= 0; i--) { int *value = array_pop(array); mu_assert(value != NULL, "Shouldn't get NULL"); mu_assert(*value == i * 333, "Wrong value"); free(value); } }
void stats_pool_copy_deinit(struct stats_pool *stp, struct hash_table **sit) { uint32_t nserver; uint32_t i; struct stats_server *sts; stats_metric_deinit(&stp->metric); string_deinit(&stp->name); nserver = array_n(&stp->server); for (i = 0;i < nserver;i++) { sts = array_pop(&stp->server); string_deinit(&stp->name); stats_metric_deinit(&sts->metric); } array_deinit(&stp->server); assoc_destroy_table(*sit); (*sit) = NULL; }
void *hmap_delete(t_hmap *map, void *key) { t_uint hash; void *data; t_array *contents; int i; t_node_h nh; contents = hmap_find_contents(map, key, 0, &hash); hash = 0; if (!contents) return (NULL); if ((i = hmap_get_node(map, hash, contents, key)) == -1) return (NULL); nh.node = array_get(contents, i); data = nh.node->data; free(nh.node); nh.ending = array_pop(contents); if (nh.ending != nh.node) array_set(contents, i, nh.ending); return (data); }
static void test_array(void **state) { int ret = 0; array_t(int) arr; array_init(arr); /* Basic access */ assert_int_equal(arr.len, 0); assert_int_equal(array_push(arr, 5), 0); assert_int_equal(arr.at[0], 5); assert_int_equal(array_tail(arr), 5); array_clear(arr); /* Reserve capacity and fill. */ assert_true(array_reserve(arr, 5) >= 0); for (unsigned i = 0; i < 100; ++i) { ret = array_push(arr, i); assert_true(ret >= 0); } /* Make sure reservation holds. */ assert_true(array_reserve(arr, 5) >= 0); /* Delete elements. */ array_del(arr, 0); while (arr.len > 0) { array_pop(arr); } /* Overfill. */ for (unsigned i = 0; i < 4096; ++i) { ret = array_push(arr, i); assert_true(ret >= 0); } array_clear(arr); }
static void conf_pool_deinit(conf_pool *cp) { sds *str; if(cp == NULL){ return; } cp->type = CONF_UNSET_GROUP; if(cp->servers != NULL){ while(array_n(cp->servers) > 0){ str = array_pop(cp->servers); sdsfree(*str); } array_destroy(cp->servers); cp->servers = CONF_UNSET_PTR; } cp->hash = CONF_UNSET_HASH; cp->distribution = CONF_UNSET_DIST; if(cp->hash_tag != NULL){ sdsfree(cp->hash_tag); cp->hash_tag = CONF_UNSET_PTR; } if(cp->redis_auth != NULL){ sdsfree(cp->redis_auth); cp->redis_auth = CONF_UNSET_PTR; } cp->redis_db = CONF_UNSET_NUM; cp->timeout = CONF_UNSET_NUM; cp->backlog = CONF_UNSET_NUM; }
int main() { array_t a; char **p; array_init(&a, sizeof(char *)); p = (char **)array_push(&a); *p = "aaaa"; p = (char **)array_push(&a); *p = "bbbb"; p = (char **)array_push(&a); *p = "cccc"; p = (char **)array_push(&a); *p = "dddd"; p = (char **)array_push(&a); while ((p = array_pop(&a)) != NULL) { printf("popped: %s\n", *p); } array_destroy(&a); return 0; }
static unsigned int* _random_thread_allocate( void ) { unsigned int* buffer; mutex_lock( _random_mutex ); //Grab a free state buffer or allocate if none available if( !array_size( _random_available_state ) ) { buffer = _random_allocate_buffer(); array_push( _random_available_state, buffer ); } else { buffer = _random_available_state[ array_size( _random_available_state ) - 1 ]; array_pop( _random_available_state ); } mutex_unlock( _random_mutex ); set_thread_state( buffer ); return buffer; }
void server_pool_deinit(struct array *server_pool) { uint32_t i, npool; for (i = 0, npool = array_n(server_pool); i < npool; i++) { struct server_pool *sp; sp = array_pop(server_pool); ASSERT(sp->p_conn == NULL); ASSERT(TAILQ_EMPTY(&sp->c_conn_q) && sp->dn_conn_q == 0); server_deinit(&sp->server); sp->nlive_server = 0; log_debug(LOG_DEBUG, "deinit pool %"PRIu32" '%.*s'", sp->idx, sp->name.len, sp->name.data); } array_deinit(server_pool); log_debug(LOG_DEBUG, "deinit %"PRIu32" pools", npool); }
static int check_response(redis_node *rnode, struct msg *r) { int ret; rmtContext *ctx = rnode->ctx; struct msg *resp, *msg = NULL; check_data *chdata; check_unit *cunit; char extra_err[50]; struct array args; sds *arg; struct array *bulks1 = NULL, *bulks2 = NULL; sds *bulk1, *bulk2; if (r == NULL) { return RMT_ERROR; } extra_err[0] = '\0'; resp = r->peer; r->peer = NULL; array_init(&args, 3, sizeof(sds)); ASSERT(r->request && r->sent); ASSERT(resp != NULL && resp->request == 0); cunit = (check_unit *)r->ptr; chdata = cunit->cdata->data; if(resp->type == MSG_RSP_REDIS_ERROR){ log_warn("Response from node[%s] for %s is error", rnode->addr, msg_type_string(r->type)); goto error; } if (cunit->state == CHECK_UNIT_STATE_GET_KEY) { ASSERT(cunit->key == NULL); ASSERT(cunit->key_type == -1); ASSERT(cunit->result1 == NULL && cunit->result2 == NULL); ASSERT(cunit->srnode == rnode); if (resp->type != MSG_RSP_REDIS_BULK) { log_error("ERROR: the response type for command 'randomkey' from node[%s] is error: %s", rnode->addr, msg_type_string(resp->type)); goto error; } if (msg_cmp_str(resp, (const uint8_t*)REDIS_REPLY_BULK_NULL, rmt_strlen(REDIS_REPLY_BULK_NULL)) == 0) { /* source group may have no keys, stop it */ cunit->cdata->keys_count --; goto done; } cunit->key = redis_msg_response_get_bulk_string(resp); if (cunit->key == NULL) { log_error("ERROR: get bulk string from response of node[%s] failed, " "bulk_len: %"PRIu32", bulk_start: %p", rnode->addr, resp->bulk_len, resp->bulk_start); goto error; } if (ctx->filter != NULL && !stringmatchlen(ctx->filter, sdslen(ctx->filter), cunit->key, sdslen(cunit->key), 0)) { goto done; } ASSERT(sdslen(cunit->key) == resp->bulk_len); msg = msg_get(r->mb, 1, REDIS_DATA_TYPE_CMD); if (msg == NULL) { log_error("ERROR: out of memory."); goto error; } arg = array_push(&args); *arg = sdsnew("type"); arg = array_push(&args); *arg = sdsdup(cunit->key); ret = redis_msg_append_command_full_safe(msg, &args); if (ret != RMT_OK) { log_error("ERROR: msg append multi bulk len failed."); goto error; } while (array_n(&args) > 0) { arg = array_pop(&args); sdsfree(*arg); } msg->ptr = cunit; msg->resp_check = check_response; ret = prepare_send_msg(rnode, msg, rnode); if (ret != RMT_OK) { log_error("ERROR: prepare send msg node[%s] failed.", rnode->addr); goto error; } cunit->state = CHECK_UNIT_STATE_GET_TYPE; goto next_step; } if (cunit->state == CHECK_UNIT_STATE_GET_TYPE) { ASSERT(cunit->key != NULL); ASSERT(cunit->key_type == -1); ASSERT(cunit->result1 == NULL && cunit->result2 == NULL); ASSERT(cunit->srnode == rnode); if (resp->type != MSG_RSP_REDIS_STATUS) { log_error("ERROR: the response type for command 'type' from node[%s] is error: %s", rnode->addr, msg_type_string(resp->type)); goto error; } if (msg_cmp_str(resp, (const uint8_t*)REDIS_REPLY_STATUS_NONE, rmt_strlen(REDIS_REPLY_STATUS_NONE)) == 0) { /* This key doesn't exit, may be expired or evicted */ goto done; } msg = msg_get(r->mb, 1, REDIS_DATA_TYPE_CMD); if (msg == NULL) { log_error("ERROR: out of memory."); goto error; } if (msg_cmp_str(resp, (const uint8_t*)REDIS_REPLY_STATUS_STRING, rmt_strlen(REDIS_REPLY_STATUS_STRING)) == 0) { cunit->key_type = REDIS_STRING; arg = array_push(&args); *arg = sdsnew("get"); arg = array_push(&args); *arg = sdsdup(cunit->key); ret = redis_msg_append_command_full_safe(msg, &args); if (ret != RMT_OK) { log_error("ERROR: msg append multi bulk len failed."); goto error; } while (array_n(&args) > 0) { arg = array_pop(&args); sdsfree(*arg); } } else if (msg_cmp_str(resp, (const uint8_t*)REDIS_REPLY_STATUS_LIST, rmt_strlen(REDIS_REPLY_STATUS_LIST)) == 0) { cunit->key_type = REDIS_LIST; arg = array_push(&args); *arg = sdsnew("lrange"); arg = array_push(&args); *arg = sdsdup(cunit->key); arg = array_push(&args); *arg = sdsnew("0"); arg = array_push(&args); *arg = sdsnew("-1"); ret = redis_msg_append_command_full_safe(msg, &args); if (ret != RMT_OK) { log_error("ERROR: msg append multi bulk len failed."); goto error; } while (array_n(&args) > 0) { arg = array_pop(&args); sdsfree(*arg); } } else if (msg_cmp_str(resp, (const uint8_t*)REDIS_REPLY_STATUS_SET, rmt_strlen(REDIS_REPLY_STATUS_SET)) == 0) { cunit->key_type = REDIS_SET; arg = array_push(&args); *arg = sdsnew("smembers"); arg = array_push(&args); *arg = sdsdup(cunit->key); ret = redis_msg_append_command_full_safe(msg, &args); if (ret != RMT_OK) { log_error("ERROR: msg append multi bulk len failed."); goto error; } while (array_n(&args) > 0) { arg = array_pop(&args); sdsfree(*arg); } } else if (msg_cmp_str(resp, (const uint8_t*)REDIS_REPLY_STATUS_ZSET, rmt_strlen(REDIS_REPLY_STATUS_ZSET)) == 0) { cunit->key_type = REDIS_ZSET; arg = array_push(&args); *arg = sdsnew("zrange"); arg = array_push(&args); *arg = sdsdup(cunit->key); arg = array_push(&args); *arg = sdsnew("0"); arg = array_push(&args); *arg = sdsnew("-1"); ret = redis_msg_append_command_full_safe(msg, &args); if (ret != RMT_OK) { log_error("ERROR: msg append multi bulk len failed."); goto error; } while (array_n(&args) > 0) { arg = array_pop(&args); sdsfree(*arg); } } else if (msg_cmp_str(resp, (const uint8_t*)REDIS_REPLY_STATUS_HASH, rmt_strlen(REDIS_REPLY_STATUS_HASH)) == 0) { cunit->key_type = REDIS_HASH; arg = array_push(&args); *arg = sdsnew("hgetall"); arg = array_push(&args); *arg = sdsdup(cunit->key); ret = redis_msg_append_command_full_safe(msg, &args); if (ret != RMT_OK) { log_error("ERROR: msg append multi bulk len failed."); goto error; } while (array_n(&args) > 0) { arg = array_pop(&args); sdsfree(*arg); } } else { log_error("ERROR: response key type from node[%s] is error: ", rnode->addr); goto error; } msg->ptr = cunit; msg->resp_check = check_response; ret = send_msg_to_all(cunit, msg); if (ret != RMT_OK) { log_error("ERROR: send msg to source and target group failed."); goto error; } cunit->state = CHECK_UNIT_STATE_GET_VALUE; goto next_step; } if (cunit->state == CHECK_UNIT_STATE_GET_VALUE) { ASSERT(cunit->key != NULL); ASSERT(cunit->key_type >= 0); ASSERT(cunit->result1 == NULL || cunit->result2 == NULL); if (cunit->key_type == REDIS_STRING) { if (resp->type != MSG_RSP_REDIS_BULK) { log_error("ERROR: the response type for %s from node[%s] is error: %s", rnode->addr, msg_type_string(r->type), msg_type_string(resp->type)); goto error; } } else if (cunit->key_type == REDIS_LIST) { } else if (cunit->key_type == REDIS_SET) { } else if (cunit->key_type == REDIS_ZSET) { } else if (cunit->key_type == REDIS_HASH) { } else { NOT_REACHED(); } if (cunit->result1 == NULL) { cunit->result1 = resp; resp = NULL; } else if (cunit->result2 == NULL) { cunit->result2 = resp; resp = NULL; } else { NOT_REACHED(); } if (cunit->result1 != NULL && cunit->result2 != NULL) { if (cunit->key_type == REDIS_SET) { uint32_t j; bulks1 = get_multi_bulk_array_from_mbuf_list(cunit->result1->data); bulks2 = get_multi_bulk_array_from_mbuf_list(cunit->result2->data); if (bulks1 == NULL || bulks2 == NULL) { log_error("ERROR: get multi bulk array from mbufs failed"); goto error; } if (array_n(bulks1) != array_n(bulks2)) { chdata->err_inconsistent_value_keys_count ++; rmt_safe_snprintf(extra_err, 50, ", value is inconsistent\0"); goto error; } array_sort(bulks1, string_binary_cmp); array_sort(bulks2, string_binary_cmp); for (j = 0; j < array_n(bulks1); j ++) { bulk1 = array_get(bulks1, j); bulk2 = array_get(bulks2, j); if (string_binary_cmp(bulk1, bulk2) != 0) { chdata->err_inconsistent_value_keys_count ++; rmt_safe_snprintf(extra_err, 50, ", value is inconsistent\0"); goto error; } } } else if (cunit->key_type == REDIS_HASH) { struct array *hash_datas1, *hash_datas2; uint32_t hash_len; uint32_t j; struct hash_data *hd1, *hd2; hash_datas1 = hash_datas2 = NULL; bulks1 = get_multi_bulk_array_from_mbuf_list(cunit->result1->data); bulks2 = get_multi_bulk_array_from_mbuf_list(cunit->result2->data); if (bulks1 == NULL || bulks2 == NULL) { log_error("ERROR: get multi bulk array from mbufs failed"); goto error; } if (array_n(bulks1)%2 != 0 || array_n(bulks2)%2 != 0) { log_error("ERROR: bad hash value"); goto error; } if (array_n(bulks1) != array_n(bulks2)) { chdata->err_inconsistent_value_keys_count ++; rmt_safe_snprintf(extra_err, 50, ", value is inconsistent\0"); goto error; } hash_len = array_n(bulks1)/2; hash_datas1 = array_create(hash_len, sizeof(struct hash_data)); hash_datas2 = array_create(hash_len, sizeof(struct hash_data)); for (j = 0; j < hash_len; j ++) { hd1 = array_push(hash_datas1); hd2 = array_push(hash_datas2); bulk1 = array_pop(bulks1); bulk2 = array_pop(bulks1); hd1->field = *bulk1; hd1->value = *bulk2; bulk1 = array_pop(bulks2); bulk2 = array_pop(bulks2); hd2->field = *bulk1; hd2->value = *bulk2; } array_sort(hash_datas1, hash_data_field_cmp); array_sort(hash_datas2, hash_data_field_cmp); for (j = 0; j < array_n(bulks1); j ++) { hd1 = array_get(hash_datas1, j); hd2 = array_get(hash_datas2, j); if (string_binary_cmp(hd1->field, hd2->field) != 0) { chdata->err_inconsistent_value_keys_count ++; rmt_safe_snprintf(extra_err, 50, ", value is inconsistent\0"); if (hash_datas1 != NULL) { while (array_n(hash_datas1) > 0) { hd1 = array_pop(hash_datas1); sdsfree(hd1->field); sdsfree(hd1->value); } array_destroy(hash_datas1); hash_datas1 = NULL; } if (hash_datas2 != NULL) { while (array_n(hash_datas2) > 0) { hd2 = array_pop(hash_datas2); sdsfree(hd2->field); sdsfree(hd2->value); } array_destroy(hash_datas2); hash_datas2 = NULL; } goto error; } if (string_binary_cmp(hd1->value, hd2->value) != 0) { chdata->err_inconsistent_value_keys_count ++; rmt_safe_snprintf(extra_err, 50, ", value is inconsistent\0"); if (hash_datas1 != NULL) { while (array_n(hash_datas1) > 0) { hd1 = array_pop(hash_datas1); sdsfree(hd1->field); sdsfree(hd1->value); } array_destroy(hash_datas1); hash_datas1 = NULL; } if (hash_datas2 != NULL) { while (array_n(hash_datas2) > 0) { hd2 = array_pop(hash_datas2); sdsfree(hd2->field); sdsfree(hd2->value); } array_destroy(hash_datas2); hash_datas2 = NULL; } goto error; } } if (hash_datas1 != NULL) { while (array_n(hash_datas1) > 0) { hd1 = array_pop(hash_datas1); sdsfree(hd1->field); sdsfree(hd1->value); } array_destroy(hash_datas1); hash_datas1 = NULL; } if (hash_datas2 != NULL) { while (array_n(hash_datas2) > 0) { hd2 = array_pop(hash_datas2); sdsfree(hd2->field); sdsfree(hd2->value); } array_destroy(hash_datas2); hash_datas2 = NULL; } } else if (msg_data_compare(cunit->result1, cunit->result2) != 0) { chdata->err_inconsistent_value_keys_count ++; rmt_safe_snprintf(extra_err, 50, ", value is inconsistent\0"); goto error; } msg_put(cunit->result1); msg_free(cunit->result1); cunit->result1 = NULL; msg_put(cunit->result2); msg_free(cunit->result2); cunit->result2 = NULL; if (bulks1 != NULL) { while (array_n(bulks1) > 0) { bulk1 = array_pop(bulks1); sdsfree(*bulk1); } array_destroy(bulks1); bulks1 = NULL; } if (bulks2 != NULL) { while (array_n(bulks2) > 0) { bulk2 = array_pop(bulks2); sdsfree(*bulk2); } array_destroy(bulks2); bulks2 = NULL; } msg = msg_get(r->mb, 1, REDIS_DATA_TYPE_CMD); if (msg == NULL) { log_error("ERROR: out of memory."); goto error; } arg = array_push(&args); *arg = sdsnew("ttl"); arg = array_push(&args); *arg = sdsdup(cunit->key); ret = redis_msg_append_command_full_safe(msg, &args); if (ret != RMT_OK) { log_error("ERROR: msg append multi bulk len failed."); goto error; } while (array_n(&args) > 0) { arg = array_pop(&args); sdsfree(*arg); } msg->ptr = cunit; msg->resp_check = check_response; ret = send_msg_to_all(cunit, msg); if (ret != RMT_OK) { log_error("ERROR: send msg to source and target group failed."); goto error; } cunit->state = CHECK_UNIT_STATE_GET_EXPIRE; } goto next_step; } if (cunit->state == CHECK_UNIT_STATE_GET_EXPIRE) { ASSERT(cunit->key != NULL); ASSERT(cunit->key_type >= 0); ASSERT(cunit->result1 == NULL || cunit->result2 == NULL); if (resp->type != MSG_RSP_REDIS_INTEGER) { log_error("ERROR: the response type for command 'ttl' from node[%s] is error: %s", rnode->addr, msg_type_string(resp->type)); goto error; } if (cunit->result1 == NULL) { cunit->result1 = resp; resp = NULL; } else if (cunit->result2 == NULL) { cunit->result2 = resp; resp = NULL; } else { NOT_REACHED(); } if (cunit->result1 != NULL && cunit->result2 != NULL) { if (msg_data_compare(cunit->result1, cunit->result2) != 0) { int mistake = (int)cunit->result1->integer - (int)cunit->result2->integer; ASSERT(mistake != 0); if (abs(mistake) > TTL_MISTAKE_CAN_BE_ACCEPT) { chdata->err_inconsistent_expire_keys_count ++; rmt_safe_snprintf(extra_err, 50, ", remaining time are %"PRIu32" and %"PRIu32"\0", cunit->result1->integer, cunit->result2->integer); goto error; } } /* OK, this key is consistent between source group and target group */ goto done; } goto next_step; } done: check_unit_destroy(cunit); next_step: msg_put(r); msg_free(r); if (resp != NULL) { msg_put(resp); msg_free(resp); } array_deinit(&args); return RMT_OK; error: chdata->err_check_keys_count ++; if (cunit->key != NULL) { log_error("ERROR: key checked failed: %s%s. key(len:%zu, type:%s): %.*s", get_check_error(cunit), extra_err, sdslen(cunit->key), get_redis_type_string(cunit->key_type), sdslen(cunit->key), cunit->key); } else { log_error("ERROR: key checked failed: %s%s.", get_check_error(cunit), extra_err); } MSG_DUMP(r, LOG_ERR, 1); msg_put(r); msg_free(r); if (resp != NULL) { MSG_DUMP(resp, LOG_ERR, 1); msg_put(resp); msg_free(resp); } if (msg != NULL) { msg_put(msg); msg_free(msg); } check_unit_destroy(cunit); while (array_n(&args) > 0) { arg = array_pop(&args); sdsfree(*arg); } array_deinit(&args); if (bulks1 != NULL) { while (array_n(bulks1) > 0) { bulk1 = array_pop(bulks1); sdsfree(*bulk1); } array_destroy(bulks1); bulks1 = NULL; } if (bulks2 != NULL) { while (array_n(bulks2) > 0) { bulk2 = array_pop(bulks2); sdsfree(*bulk2); } array_destroy(bulks2); bulks2 = NULL; } return RMT_OK; }
char * conf_add_server(struct conf *cf, struct command *cmd, void *conf) { rstatus_t status; struct array *a; struct string *value; struct conf_server *field; uint8_t *p, *q, *start; uint8_t *name, *port, *weight; uint32_t k, namelen, portlen, weightlen; p = conf; a = (struct array *)(p + cmd->offset); field = array_push(a); if (field == NULL) { return CONF_ERROR; } conf_server_init(field); value = array_top(&cf->arg); status = string_duplicate(&field->pname, value); if (status != NC_OK) { array_pop(a); return CONF_ERROR; } /* parse "hostname:port:weight" from the end */ p = value->data + value->len - 1; start = value->data; name = NULL; namelen = 0; weight = NULL; weightlen = 0; port = NULL; portlen = 0; for (k = 0; k < 2; k++) { q = nc_strrchr(p, start, ':'); if (q == NULL) { break; } switch (k) { case 0: weight = q + 1; weightlen = (uint32_t)(p - weight + 1); break; case 1: port = q + 1; portlen = (uint32_t)(p - port + 1); break; default: NOT_REACHED(); } p = q - 1; } if (k != 2) { return "has an invalid \"hostname:port:weight\" format string"; } name = start; namelen = (uint32_t)(p - start + 1); field->weight = nc_atoi(weight, weightlen); if (field->weight < 0) { return "has an invalid weight in \"hostname:port:weight\" format string"; } field->port = nc_atoi(port, portlen); if (field->port < 0 || !nc_valid_port(field->port)) { return "has an invalid port in \"hostname:port:weight\" format string"; } status = string_copy(&field->name, name, namelen); if (status != NC_OK) { return CONF_ERROR; } status = nc_resolve(&field->name, field->port, &field->info); if (status != NC_OK) { return CONF_ERROR; } field->valid = 1; return CONF_OK; }
char * conf_add_server(struct conf *cf, struct command *cmd, void *conf) { rstatus_t status; struct array *a; struct string *value; struct conf_server *field; uint8_t *p, *q, *start; uint8_t *pname, *addr, *port, *weight, *name; uint32_t k, pnamelen, addrlen, portlen, weightlen, namelen; struct string address; char delim[] = " ::"; string_init(&address); p = conf; a = (struct array *)(p + cmd->offset); field = array_push(a); if (field == NULL) { return CONF_ERROR; } conf_server_init(field); value = array_top(&cf->arg); /* parse "hostname:port:weight [name]" from the end */ p = value->data + value->len - 1; start = value->data; addr = NULL; addrlen = 0; weight = NULL; weightlen = 0; port = NULL; portlen = 0; name = NULL; namelen = 0; for (k = 0; k < sizeof(delim); k++) { q = nc_strrchr(p, start, delim[k]); if (q == NULL) { if (k == 0) { /* * name in "hostname:port:weight [name]" format string is * optional */ continue; } break; } switch (k) { case 0: name = q + 1; namelen = (uint32_t)(p - name + 1); break; case 1: weight = q + 1; weightlen = (uint32_t)(p - weight + 1); break; case 2: port = q + 1; portlen = (uint32_t)(p - port + 1); break; default: NOT_REACHED(); } p = q - 1; } if (k != 3) { return "has an invalid \"hostname:port:weight [name]\" format string"; } pname = value->data; pnamelen = namelen > 0 ? value->len - (namelen + 1) : value->len; status = string_copy(&field->pname, pname, pnamelen); if (status != NC_OK) { array_pop(a); return CONF_ERROR; } addr = start; addrlen = (uint32_t)(p - start + 1); field->weight = nc_atoi(weight, weightlen); if (field->weight < 0) { return "has an invalid weight in \"hostname:port:weight [name]\" format string"; } field->port = nc_atoi(port, portlen); if (field->port < 0 || !nc_valid_port(field->port)) { return "has an invalid port in \"hostname:port:weight [name]\" format string"; } if (name == NULL) { /* * To maintain backward compatibility with libmemcached, we don't * include the port as the part of the input string to the consistent * hashing algorithm, when it is equal to 11211. */ if (field->port == CONF_DEFAULT_KETAMA_PORT) { name = addr; namelen = addrlen; } else { name = addr; namelen = addrlen + 1 + portlen; } } status = string_copy(&field->name, name, namelen); if (status != NC_OK) { return CONF_ERROR; } status = string_copy(&address, addr, addrlen); if (status != NC_OK) { return CONF_ERROR; } status = nc_resolve(&address, field->port, &field->info); if (status != NC_OK) { string_deinit(&address); return CONF_ERROR; } string_deinit(&address); field->valid = 1; return CONF_OK; }
static data_config *configparser_pop(config_t *ctx) { data_config *old = ctx->current; ctx->current = (data_config *) array_pop(ctx->configs_stack); return old; }
int main(int argc, char *argv[]) { struct array a; struct array_iterator ai; int i; int *t, *t_arr; while ((i = getopt(argc, argv, "vi:")) != -1) { switch (i) { case 'v': ++verbose; break; case 'i': MAX_ITEMS = atoi(optarg); break; default: fprintf(stderr, "bad option\n"); exit(1); } } assert(t_arr = malloc(MAX_ITEMS * sizeof(int))); array_init(&a, 100); verbose_print(1, "start\n"); for (i = 0; i < MAX_ITEMS; i++) { t = t_arr + i; *t = i; assert(array_put(&a, t) == i); } for (i = 0; i < MAX_ITEMS; i += 2) { t = t_arr + i; assert(array_remove(&a, t) == t); } for (i = 1; i < MAX_ITEMS; i += 2) { t = t_arr + i; assert(array_pop(&a) == t); } for (i = 0; i < MAX_ITEMS; i += 2) { t = t_arr + i; assert(array_put_at(&a, i, t) == NULL); } for (i = 1; i < MAX_ITEMS; i += 2) { t = t_arr + i; assert(array_put(&a, t) == i); } for (i = 0; i < MAX_ITEMS; i += 2) { t = t_arr + i; assert(array_remove_at(&a, i) == t); } array_iter_set(&ai, &a); i = 1; while ((t = array_iter_get(&ai))) { assert(*t == i); i += 2; verbose_print(2, "%d ", *t); } array_iter_end(&ai); printf("\n"); array_free(&a); return 0; }
char * conf_add_server(struct conf *cf, struct command *cmd, void *conf) { rstatus_t status; struct array *a; struct string *value; struct conf_server *field; uint8_t *p, *q, *start; uint8_t *pname, *addr, *port, *weight, *name; uint32_t k, delimlen, pnamelen, addrlen, portlen, weightlen, namelen; char delim[] = " ::"; p = conf; a = (struct array *)(p + cmd->offset); field = array_push(a); if (field == NULL) { return CONF_ERROR; } conf_server_init(field); value = array_top(&cf->arg); /* parse "hostname:port:weight [name]" or "/path/unix_socket:weight [name]" from the end */ p = value->data + value->len - 1; start = value->data; addr = NULL; addrlen = 0; weight = NULL; weightlen = 0; port = NULL; portlen = 0; name = NULL; namelen = 0; delimlen = value->data[0] == '/' ? 2 : 3; for (k = 0; k < sizeof(delim); k++) { q = nc_strrchr(p, start, delim[k]); if (q == NULL) { if (k == 0) { /* * name in "hostname:port:weight [name]" format string is * optional */ continue; } break; } switch (k) { case 0: name = q + 1; namelen = (uint32_t)(p - name + 1); break; case 1: weight = q + 1; weightlen = (uint32_t)(p - weight + 1); break; case 2: port = q + 1; portlen = (uint32_t)(p - port + 1); break; default: NOT_REACHED(); } p = q - 1; } if (k != delimlen) { return "has an invalid \"hostname:port:weight [name]\"or \"/path/unix_socket:weight [name]\" format string"; } pname = value->data; pnamelen = namelen > 0 ? value->len - (namelen + 1) : value->len; status = string_copy(&field->pname, pname, pnamelen); if (status != NC_OK) { array_pop(a); return CONF_ERROR; } addr = start; addrlen = (uint32_t)(p - start + 1); field->weight = nc_atoi(weight, weightlen); if (field->weight < 0) { return "has an invalid weight in \"hostname:port:weight [name]\" format string"; } else if (field->weight == 0) { return "has a zero weight in \"hostname:port:weight [name]\" format string"; } if (value->data[0] != '/') { field->port = nc_atoi(port, portlen); if (field->port < 0 || !nc_valid_port(field->port)) { return "has an invalid port in \"hostname:port:weight [name]\" format string"; } } if (name == NULL) { /* * To maintain backward compatibility with libmemcached, we don't * include the port as the part of the input string to the consistent * hashing algorithm, when it is equal to 11211. */ if (field->port == CONF_DEFAULT_KETAMA_PORT) { name = addr; namelen = addrlen; } else { name = addr; namelen = addrlen + 1 + portlen; } } status = string_copy(&field->name, name, namelen); if (status != NC_OK) { return CONF_ERROR; } status = string_copy(&field->addrstr, (uint8_t *)addr, addrlen); if (status != NC_OK) { return CONF_ERROR; } /* * The address resolution of the backend server hostname is lazy. * The resolution occurs when a new connection to the server is * created, which could either be the first time or every time * the server gets re-added to the pool after an auto ejection */ field->valid = 1; return CONF_OK; }