示例#1
0
文件: ctl.c 项目: hellocjfeii/TSDB
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;
}
示例#2
0
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; 
}