int ctl_cmd_parse(struct data_node *p_node) { int ret = 0; unsigned int loop = 0; int ok = 0; unsigned int i, j = 0; int offset = 0; size_t mlen = 0; char *p_new = NULL; char *p_old = NULL; char *result = NULL; char ret_number[16] = { 0 }; int size = 0; int sum = 0; if (p_node->status == X_MALLOC_FAILED) { add_send_node(p_node, OPT_NO_MEMORY, strlen(OPT_NO_MEMORY)); return X_MALLOC_FAILED; } if (p_node->gtlen > MAX_CMD_LEN) { add_send_node(p_node, OPT_DATA_TOO_LARGE, strlen(OPT_DATA_TOO_LARGE)); return X_DATA_TOO_LARGE; } /* parse cmd */ char *data = p_node->svbf; log_debug("%s", data); if (data[0] == '*') { // 1. read the arg count: if (p_node->kvs == 0) { p_new = p_old = &data[1]; CHECK_BUFFER(p_new, 0); p_node->kvs = atoi(p_old); p_node->doptr = p_new - data; } // 2. read the request name if (p_node->cmd == 0) { if (data[p_node->doptr] != '$') { goto E_OUT_PUT; } p_new = p_old = &data[p_node->doptr + 1]; CHECK_BUFFER(p_new, 0); mlen = atoi(p_old); p_old = p_new; CHECK_BUFFER(p_new, mlen); for (i = 0; i < mlen; i++) { if (*(p_old + i) > 'Z') { *(p_old + i) -= 32;/* 'A' - 'a' */ } p_node->cmd = p_node->cmd * 26 + (*(p_old + i) - 'A');/* A~Z is 26 numbers */ } p_node->doptr = p_new - data; }log_debug("%d", p_node->cmd); // 3. read a arg switch (p_node->cmd) { case LDB_SET: if (LDB_READONLY_SWITCH == 1 || p_node->kvs != LDB_SET_CNT) { goto E_OUT_PUT; } PARSE_LEN(p_node->klen); PARSE_MEMBER(p_node->key, p_node->klen); PARSE_LEN(p_node->vlen); PARSE_MEMBER(p_node->val, p_node->vlen); // x_out_time(&g_dbg_time); ok = ldb_put(g_ldb, &data[p_node->key], p_node->klen, &data[p_node->val], p_node->vlen); // x_out_time(&g_dbg_time); goto W_OUT_PUT; case LDB_DEL: if (LDB_READONLY_SWITCH == 1 || p_node->kvs < LDB_DEL_MIN) { goto E_OUT_PUT; } loop = p_node->kvs - 1; sum = 0; for (j = 0; j < loop; ++j) { PARSE_LEN(p_node->klen); PARSE_MEMBER(p_node->key, p_node->klen); ok = ldb_delete(g_ldb, &data[p_node->key], p_node->klen); if (ok < 0) { goto E_OUT_PUT; } sum += ok; p_node->kvs -= 1; p_node->key = 0; p_node->klen = 0; } goto NUM_OUT_PUT; case LDB_MSET:/* use one thread to write, otherwise (one thread should use one leveldb_writebatch_t) or (add a mutex lock) */ if (LDB_READONLY_SWITCH == 1) { goto E_OUT_PUT; } loop = (p_node->kvs - 1) / 2; if (loop < 1) { goto E_OUT_PUT; } for (j = 0; j < loop; ++j) { PARSE_LEN(p_node->klen); PARSE_MEMBER(p_node->key, p_node->klen); PARSE_LEN(p_node->vlen); PARSE_MEMBER(p_node->val, p_node->vlen); ldb_batch_put(g_ldb, &data[p_node->key], p_node->klen, &data[p_node->val], p_node->vlen); p_node->kvs -= 2; p_node->klen = 0; p_node->key = 0; p_node->vlen = 0; p_node->val = 0; } ok = ldb_batch_commit(g_ldb); goto W_OUT_PUT; case LDB_GET: if (p_node->kvs != LDB_GET_CNT) { goto E_OUT_PUT; } PARSE_LEN(p_node->klen); PARSE_MEMBER(p_node->key, p_node->klen); log_debug("key = %s", &data[ p_node->key ]); result = ldb_get(g_ldb, &data[p_node->key], p_node->klen, &size); log_debug("val = %s", result); goto R_BULK_OUT_PUT; case LDB_LRANGE: if (p_node->kvs != LDB_LRANGE_CNT) { goto E_OUT_PUT; } PARSE_LEN(p_node->klen); PARSE_MEMBER(p_node->key, p_node->klen); /* look as prefix key */ PARSE_LEN(p_node->vlen); PARSE_MEMBER(p_node->val, p_node->vlen); /* look as start time */ PARSE_LEN(p_node->vlen2); PARSE_MEMBER(p_node->val2, p_node->vlen2); /* look as end time */ log_debug("prefix key = %s", &data[ p_node->key ]); log_debug("start = %s", &data[ p_node->val ]); log_debug("end = %s", &data[ p_node->val2 ]); result = ldb_lrangeget(g_ldb, &data[p_node->key], p_node->klen, &data[p_node->val], p_node->vlen, &data[p_node->val2], p_node->vlen2, &size); goto R_MULTI_OUT_PUT; case LDB_KEYS: if (p_node->kvs != LDB_KEYS_CNT) { goto E_OUT_PUT; } PARSE_LEN(p_node->klen); PARSE_MEMBER(p_node->key, p_node->klen); result = ldb_keys(g_ldb, &data[p_node->key], p_node->klen, &size); log_debug("size = %d", size); goto R_MULTI_OUT_PUT; case LDB_INFO: if (p_node->kvs != LDB_INFO_CNT) { goto E_OUT_PUT; } result = ldb_info(g_ldb, &size); log_debug("size = %d\n", size); goto R_MULTI_OUT_PUT; case LDB_PING: if (p_node->kvs != LDB_PING_CNT) { goto E_OUT_PUT; } add_send_node(p_node, OPT_PONG, strlen(OPT_PONG)); return X_DATA_IS_ALL; case LDB_EXISTS: if (p_node->kvs != LDB_EXISTS_CNT) { goto E_OUT_PUT; } PARSE_LEN(p_node->klen); PARSE_MEMBER(p_node->key, p_node->klen); ok = ldb_exists(g_ldb, &data[p_node->key], p_node->klen); if (ok == -1) { goto E_OUT_PUT; } sum = ok; goto NUM_OUT_PUT; case LDB_QUIT: log_debug("-----------------------------------------------------"); return X_CLIENT_QUIT; default: goto E_OUT_PUT; } E_OUT_PUT: add_send_node(p_node, OPT_CMD_ERROR, strlen(OPT_CMD_ERROR)); return X_ERROR_CMD; W_OUT_PUT: if (ok == 0) { log_debug("------------------------------------------"); add_send_node(p_node, OPT_OK, strlen(OPT_OK)); return X_DATA_IS_ALL; } else { add_send_node(p_node, OPT_LDB_ERROR, strlen(OPT_LDB_ERROR)); return X_ERROR_LDB; } NUM_OUT_PUT: sprintf(ret_number, OPT_NUMBER, sum); log_debug("%s", ret_number); add_send_node(p_node, ret_number, strlen(ret_number)); return X_DATA_IS_ALL; R_BULK_OUT_PUT: if (result) { char tmp[32] = { 0 }; sprintf(tmp, "$%d\r\n", size); ret = add_send_node(p_node, tmp, strlen(tmp)); ret = add_send_node(p_node, result, size); leveldb_free(result); if (ret == X_MALLOC_FAILED) { clean_send_node(p_node); add_send_node(p_node, OPT_NO_MEMORY, strlen(OPT_NO_MEMORY)); return X_MALLOC_FAILED; } ret = add_send_node(p_node, "\r\n", 2); return X_DATA_IS_ALL; } else { if (size == 0) { add_send_node(p_node, OPT_NULL, strlen(OPT_NULL)); return X_DATA_IS_ALL; } else { add_send_node(p_node, OPT_LDB_ERROR, strlen(OPT_LDB_ERROR)); return X_ERROR_LDB; } } R_MULTI_OUT_PUT: if (result) { set_send_node(p_node, result, size); return X_DATA_IS_ALL; } else { if (size == 0) { add_send_node(p_node, OPT_NULL, strlen(OPT_NULL)); return X_DATA_IS_ALL; } else { add_send_node(p_node, OPT_LDB_ERROR, strlen(OPT_LDB_ERROR)); return X_ERROR_LDB; } } } else if (data[0] == '$') { #if 0 // 1. read the request name if (p_node->cmd == 0) { p_new = p_old = &data[1]; CHECK_BUFFER(p_new, 0); mlen = atoi( p_old ); p_old = p_new; CHECK_BUFFER(p_new, mlen); for (i = 0; i < mlen; i++) { p_node->cmd = p_node->cmd * 26 + ( *(p_old + i) - 'A' );/* A~Z is 26 numbers */ } p_node->doptr = p_new - data; } log_debug("%d\n", p_node->cmd); // 2. read a arg switch (p_node->cmd) { case LDB_QUIT: return CLIENT_QUIT; default: log_debug("-----------------------------------------------------\n"); return -1; } //TODO #endif add_send_node(p_node, OPT_CMD_ERROR, strlen(OPT_CMD_ERROR)); return X_ERROR_CMD; } else { add_send_node(p_node, OPT_CMD_ERROR, strlen(OPT_CMD_ERROR)); return X_ERROR_CMD; } return X_DATA_IS_ALL; }
int rds_cmd_parse(struct data_node *p_node) { int loop = 0; int i,j = 0; int offset = 0; size_t mlen = 0; char *p_new = NULL; char *p_old = NULL; /* parse cmd */ char *data = p_node->recv.buf_addr; struct redis_parser *p_parser = &p_node->redis_info.rp; struct redis_status *p_status = &p_node->redis_info.rs; x_printf(D, "%s\n", data); if (data[0] == '*'){ // 1. read the arg count: if (p_parser->kvs == 0) { p_new = p_old = &data[1]; CHECK_BUFFER(p_new, 0); p_parser->kvs = atoi( p_old ); p_parser->doptr = p_new - data; rds_reset_status(p_node); } // 2. read the request name if (p_parser->cmd == 0){ if (data[ p_parser->doptr ] != '$'){ return X_PARSE_ERROR; } p_new = p_old = &data[ p_parser->doptr + 1]; CHECK_BUFFER(p_new, 0); mlen = atoi( p_old ); p_old = p_new; CHECK_BUFFER(p_new, mlen); for (i = 0; i < mlen; i++){ if ( *(p_old + i) > 'Z' ){ *(p_old + i) -= 32;/* 'A' - 'a' */ } p_parser->cmd = p_parser->cmd * 26 + ( *(p_old + i) - 'A' );/* A~Z is 26 numbers */ } p_parser->doptr = p_new - data; } x_printf(D, "%d\n", p_parser->cmd); // 3. read a arg switch (p_parser->cmd){ case CMD_SET: PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); PARSE_LEN(p_parser->vlen); PARSE_MEMBER_AND_STORE(p_parser->val, p_parser->vlen, p_status->vals, p_status->val_offset, p_status->vlen_array); p_status->order = SET_FUNC_ORDER; return X_DATA_IS_ALL; case CMD_LPUSHX: PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); PARSE_LEN(p_parser->vlen); PARSE_MEMBER_AND_STORE(p_parser->val, p_parser->vlen, p_status->vals, p_status->val_offset, p_status->vlen_array); p_status->order = LPUSHX_FUNC_ORDER; return X_DATA_IS_ALL; case CMD_RPUSHX: PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); PARSE_LEN(p_parser->vlen); PARSE_MEMBER_AND_STORE(p_parser->val, p_parser->vlen, p_status->vals, p_status->val_offset, p_status->vlen_array); p_status->order = RPUSHX_FUNC_ORDER; return X_DATA_IS_ALL; case CMD_DEL: PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); //p_status->type = BIT8_TASK_TYPE_ALONE; //p_status->func = NULL;//FIXME return X_DATA_IS_ALL; case CMD_MSET:/* use one thread to write, otherwise add a mutex lock */ loop = (p_parser->kvs - 1) / 2; for (j = 0; j < loop; j++){ PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); PARSE_LEN(p_parser->vlen); PARSE_MEMBER_AND_STORE(p_parser->val, p_parser->vlen, p_status->vals, p_status->val_offset, p_status->vlen_array); p_parser->kvs -= 2; p_parser->klen = 0; p_parser->key = 0; p_parser->vlen = 0; p_parser->val = 0; } //p_status->type = BIT8_TASK_TYPE_ALONE; //p_status->func = NULL;//FIXME return X_DATA_IS_ALL; case CMD_HSET: PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); PARSE_LEN(p_parser->flen); PARSE_MEMBER_AND_STORE(p_parser->fld, p_parser->flen, p_status->flds, p_status->fld_offset, p_status->flen_array); PARSE_LEN(p_parser->vlen); PARSE_MEMBER_AND_STORE(p_parser->val, p_parser->vlen, p_status->vals, p_status->val_offset, p_status->vlen_array); p_status->order = HSET_FUNC_ORDER; return X_DATA_IS_ALL; case CMD_GET: PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); //p_status->type = BIT8_TASK_TYPE_ALONE; //p_status->func = NULL;//FIXME return X_DATA_IS_ALL; //case CMD_MGET: case CMD_HMGET://FIXME key switch filed PARSE_LEN(p_parser->flen); PARSE_MEMBER_AND_STORE(p_parser->fld, p_parser->flen, p_status->flds, p_status->fld_offset, p_status->flen_array); loop = p_parser->kvs - 2; for (j = 0; j < loop; j++){ PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); p_parser->kvs --; p_parser->klen = 0; p_parser->key = 0; } p_status->order = HMGET_FUNC_ORDER; return X_DATA_IS_ALL; case CMD_HGETALL: PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); p_status->order = HGETALL_FUNC_ORDER; //p_status->type = BIT8_TASK_TYPE_ALONE; //p_status->func = NULL;//FIXME return X_DATA_IS_ALL; case CMD_LRANGE: /* look as start key */ PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); /* look as end key */ PARSE_LEN(p_parser->vlen); PARSE_MEMBER_AND_STORE(p_parser->val, p_parser->vlen, p_status->vals, p_status->val_offset, p_status->vlen_array); //p_status->type = BIT8_TASK_TYPE_ALONE; //p_status->func = NULL;//FIXME return X_DATA_IS_ALL; case CMD_QUIT: return X_REQUEST_QUIT; default: return X_REQUEST_ERROR; } } else if (data[0] == '$'){ #if 0 // 1. read the request name if (p_parser->cmd == 0){ p_new = p_old = &data[1]; CHECK_BUFFER(p_new, 0); mlen = atoi( p_old ); p_old = p_new; CHECK_BUFFER(p_new, mlen); for (i = 0; i < mlen; i++){ p_parser->cmd = p_parser->cmd * 26 + ( *(p_old + i) - 'A' );/* A~Z is 26 numbers */ } p_parser->doptr = p_new - data; } x_printf(D, "%d\n", p_parser->cmd); // 2. read a arg switch (p_parser->cmd){ case CMD_QUIT: return CLIENT_QUIT; default: x_printf(D, "-----------------------------------------------------\n"); return -1; } //TODO #endif return X_REQUEST_ERROR; }else{ return X_PARSE_ERROR; } return X_DATA_IS_ALL; }