Reply CodisClient::RedisCommand(const vector<string>& command, int tt)
{
    if (command.size() < 2)
    {
        Reply reply;
        reply.SetErrorMessage("Command length should gt 2");
        return reply;
    }

    vector<string> innerCommand;

    for(size_t i=0; i<command.size(); i++)
    {
        if ((command[0] == "MGET") || (command[0] == "mget"))
        {
            if (m_BID!="" && i>0)
            {
                innerCommand.push_back(m_BID + "_" + command[i]);
            }
            else
            {
                innerCommand.push_back(command[i]);
            }
        }
        else if ((command[0] == "MSET") || (command[0] == "mset"))
        {
            if ((m_BID!="") && (i%2==1))
            {
                innerCommand.push_back(m_BID + "_" + command[i]);
            }
            else
            {
                innerCommand.push_back(command[i]);
            }
        }
        else if ((command[0] == "DEL") || (command[0] == "del"))
        {
            if ((m_BID!="") && (i>0))
            {
                innerCommand.push_back(m_BID + "_" + command[i]);
            }
            else
            {
                innerCommand.push_back(command[i]);
            }
        }
        else if (i==1 && m_BID!="")
        {
            innerCommand.push_back(m_BID + "_" + command[i]);
        }
        else
        {
            innerCommand.push_back(command[i]);
        }
    }

    vector<const char*> argv;
    vector<size_t> arglen;
    for (size_t i=0; i<innerCommand.size(); ++i)
    {
        argv.push_back(innerCommand[i].c_str());
        arglen.push_back(innerCommand[i].size());
    }
    if (!m_ConnPool)
    {
        LOG(ERROR, "connpool is null!");
        Reply reply;
        reply.SetErrorMessage("Can not fetch client from pool!!!");
        return reply;
    }
    //----
    redisContext* redis = m_ConnPool->borrowItem();
    if (!redis)
    {
        LOG(ERROR, "contetx is null!");
        Reply reply;
        reply.SetErrorMessage("context is NULL !!");
        return reply;
    }

    redisReply *reply;
    int ts = tt/1000;
    int tm = tt%1000;
    struct timeval tv = {ts, tm*1000};
    if (redisSetTimeout(redis,tv) != REDIS_OK) {
        redisFree(redis);
        redis = NULL;
        redis = m_ConnPool->create();
        if (redis == NULL)
        {
            LOG(ERROR, "reconnect faild!");
            Reply reply;
            reply.SetErrorMessage("reconnect faild!");
            return reply;
        }
        redisSetTimeout(redis,tv);
    };
    reply = (redisReply*)redisCommandArgv(redis, argv.size(), &argv[0], &arglen[0]);
    // 服务端会主动关闭掉不活跃的连接,这里处理重练并重新发送命令
    if (!reply)
    {
        redisFree(redis);
        redis = NULL;
        redis = m_ConnPool->create();
        if (redis == NULL)
        {
            LOG(ERROR, "reconnect faild!");
            Reply reply;
            reply.SetErrorMessage("reconnect faild!");
            return reply;
        }
        redisSetTimeout(redis,tv);
        reply = (redisReply*)redisCommandArgv(redis, argv.size(), &argv[0], &arglen[0]);
    }

    //// 重连后依然失败则返回
    m_ConnPool->returnItem(redis);
    if (!reply)
    {
        Reply reply;
        reply.SetErrorMessage("Do Command faild.");
        return reply;
    }

    // 如果命令发送成功则将连接放回到连接池
    //if (m_ConnPool != NULL) {
    //}
    //else {
//			cout << "m_ConnPool is NULL" << endl;
//	}
    Reply ret = Reply(reply);
    freeReplyObject(reply);
    return ret;
}
bool RedisDB::DoCommand(redisContext* (&redis), vector<string>& command, Reply& reply)
{
	vector<const char*> argv;
	vector<size_t> arglen;
	for (size_t i = 0; i < command.size(); ++i)
	{
		argv.push_back(command[i].c_str());
		arglen.push_back(command[i].size());
	}

	redisReply *rep = NULL;

	string selectCommand = string("select ") + m_RedisDBNo;

	int ret = redisAppendCommand(redis, selectCommand.c_str());
	if (ret != REDIS_OK)
	{
		if (redis != NULL)
		{
			redisFree(redis);
			redis = NULL;
		}

		redis = m_ConnPool->create();
		if (redis == NULL)
		{
			LOG(ERROR, "reconnect faild!");
			reply.SetErrorMessage("reconnect faild!");
			return false;
		}
		ret = redisAppendCommand(redis, selectCommand.c_str());
	}

	if (ret != REDIS_OK)
	{
		if (redis != NULL)
		{
			redisFree(redis);
			redis = NULL;
		}
		reply.SetErrorMessage("Do Select Command faild.");
		LOG(ERROR, "Do Select Command faild.");
		return false;
	}

	ret = redisAppendCommandArgv(redis, argv.size(), &argv[0], &arglen[0]);

	if (ret != REDIS_OK)
	{
		if (redis != NULL)
		{
			redisFree(redis);
			redis = NULL;
		}
		reply.SetErrorMessage("Do Command faild.");
		LOG(ERROR, "Do Command faild.");
		return false;
	}

	if (REDIS_OK != redisGetReply(redis, (void**) &rep))
	{
		if (redis != NULL)
		{
			redisFree(redis);
			redis = NULL;
		}
		reply.SetErrorMessage("Do Select Command faild.");
		LOG(ERROR, "Do Select Command faild.");
		return false;
	}

	if (string(rep->str) != string("OK"))
	{
		if (redis != NULL)
		{
			redisFree(redis);
			redis = NULL;
		}
		reply.SetErrorMessage(
				"Do Select Command faild, please check redis config parameter databases, it must >= 1024!");
		LOG(ERROR, "Do Select Command faild, please check redis config parameter databases, it must >= 1024!");
		return false;
	}

	if (REDIS_OK != redisGetReply(redis, (void**) &rep))
	{
		if (redis != NULL)
		{
			redisFree(redis);
			redis = NULL;
		}
		reply.SetErrorMessage("Do Command faild.");
		LOG(ERROR, "Do Command faild.");
		return false;
	}

	reply = Reply(rep);
	if (rep != NULL)
	{
		freeReplyObject(rep);
		rep = NULL;
	}

	return true;
}
vector<string> RedisDB::keys(string prefix)
{
	vector<string> keys;

	if (!m_ConnPool)
	{
		fprintf(stderr, "client pool is null!!!");
		Reply reply;
		reply.SetErrorMessage("Can not fetch client from pool!!!");
		LOG(ERROR, "client pool is null!!!");
		return keys;
	}

	vector<string> command;
	command.push_back("KEYS");
	if (prefix != "")
	{
		command.push_back(prefix + "*");
	}
	else
	{
		command.push_back("*");
	}

	vector<const char*> argv;
	vector<size_t> arglen;
	for (size_t i = 0; i < command.size(); ++i)
	{
		argv.push_back(command[i].c_str());
		arglen.push_back(command[i].size());
	}

	redisContext* redis = m_ConnPool->borrowItem();
#ifdef DEBUG
	fprintf(stdout, "real key: %s, host:%s \n", inner_key.c_str(), p->getId().c_str());
#endif

	if (!redis)
	{
		fprintf(stderr, "contetx is NULL!!");
		Reply reply;
		reply.SetErrorMessage("context is NULL !!");
		LOG(ERROR, "contetx is null!!!");
		return keys;
	}
	redisReply *reply = NULL;

	string selectCommand = string("select ") + m_RedisDBNo;

	int ret = redisAppendCommand(redis, selectCommand.c_str());
	if (ret != REDIS_OK)
	{
		if (redis != NULL)
		{
			redisFree(redis);
			redis = NULL;
		}
		redis = m_ConnPool->create();
		if (redis == NULL)
		{
			LOG(ERROR, "reconnect faild!");
			Reply reply;
			reply.SetErrorMessage("reconnect faild!");
			LOG(ERROR, "reconnect faild!");
			return keys;
		}
		ret = redisAppendCommand(redis, selectCommand.c_str());
	}

	if (ret != REDIS_OK)
	{
		if (redis != NULL)
		{
			redisFree(redis);
			redis = NULL;
		}
		Reply reply;
		reply.SetErrorMessage("Do Select Command faild.");
		LOG(ERROR, "Do Select Command faild.");
		return keys;
	}

	ret = redisAppendCommandArgv(redis, argv.size(), &argv[0], &arglen[0]);

	if (ret != REDIS_OK)
	{
		if (redis != NULL)
		{
			redisFree(redis);
			redis = NULL;
		}
		Reply reply;
		reply.SetErrorMessage("Do Command faild.");
		LOG(ERROR, "Do Command faild.");
		return keys;
	}

	if (REDIS_OK != redisGetReply(redis, (void**) &reply))
	{
		if (redis != NULL)
		{
			redisFree(redis);
			redis = NULL;
		}
		Reply reply;
		reply.SetErrorMessage("Do Select Command faild.");
		LOG(ERROR, "Do Select Command faild.");
		return keys;
	}

	if (string(reply->str) != string("OK"))
	{
		if (redis != NULL)
		{
			redisFree(redis);
			redis = NULL;
		}
		Reply reply;
		reply.SetErrorMessage(
				"Do Select Command faild, please check redis config parameter databases, it must >= 1024!");
		LOG(ERROR, "Do Select Command faild, please check redis config parameter databases, it must >= 1024!");
		return keys;
	}

	if (REDIS_OK != redisGetReply(redis, (void**) &reply))
	{
		if (redis != NULL)
		{
			redisFree(redis);
			redis = NULL;
		}
		Reply reply;
		reply.SetErrorMessage("Do Command faild.");
		LOG(ERROR, "Do Command faild.");
		return keys;
	}

	m_ConnPool->returnItem(redis);
	Reply retrep = Reply(reply);
	freeReplyObject(reply);

	for (size_t i=0; i<retrep.elements().size(); i++)
	{
		keys.push_back(retrep.elements()[i].str());
	}

	return keys;
}
Reply RedisDB::RedisCommand(vector<string> command)
{
	if (command.size() < 2)
	{
		Reply reply;
		reply.SetErrorMessage("Command length should gt 2");
		return reply;
	}

	if (!m_ConnPool)
	{
		fprintf(stderr, "client pool is null!!!");
		Reply reply;
		reply.SetErrorMessage("Can not fetch client from pool!!!");
		return reply;
	}

	//----

	redisContext* redis = m_ConnPool->borrowItem();

	if (!redis)
	{
		fprintf(stderr, "contetx is NULL!!");
		Reply reply;
		reply.SetErrorMessage("context is NULL !!");
		return reply;
	}

	Reply reply;

	bool ret = DoCommand(redis, command, reply);

	if (!ret)
	{
		if (redis != NULL)
		{
			redisFree(redis);
			redis = NULL;
		}
		redis = m_ConnPool->create();
		if (redis == NULL)
		{
			LOG(ERROR, "reconnect faild!");
			Reply reply;
			reply.SetErrorMessage("reconnect faild!");
			return reply;
		}
		ret = DoCommand(redis, command, reply);
	}

	if (ret)
	{
		m_ConnPool->returnItem(redis);
	}
	else
	{
		if (redis != NULL)
		{
			redisFree(redis);
			redis = NULL;
		}
	}

	return reply;
	//----

//	vector<const char*> argv;
//	vector<size_t> arglen;
//	for (size_t i = 0; i < command.size(); ++i)
//	{
//		argv.push_back(command[i].c_str());
//		arglen.push_back(command[i].size());
//	}
//
//	redisContext* redis = m_ConnPool->borrowItem();
//
//
//	if (!redis)
//	{
//		fprintf(stderr, "contetx is NULL!!");
//		Reply reply;
//		reply.SetErrorMessage("context is NULL !!");
//		return reply;
//	}
//	redisReply *reply = NULL;
//
//	string selectCommand = string("select ") + m_RedisDBNo;
//
//	int ret = redisAppendCommand(redis, selectCommand.c_str());
//	if (ret != REDIS_OK)
//	{
//		redisFree(redis);
//		redis = NULL;
//		redis = m_ConnPool->create();
//		if (redis == NULL)
//		{
//			LOG(ERROR, "reconnect faild!");
//			Reply reply;
//			reply.SetErrorMessage("reconnect faild!");
//			return reply;
//		}
//		ret = redisAppendCommand(redis, selectCommand.c_str());
//	}
//
//	if (ret != REDIS_OK)
//	{
//		redisFree(redis);
//		Reply reply;
//		reply.SetErrorMessage("Do Select Command faild.");
//		LOG(ERROR, "Do Select Command faild.");
//		return reply;
//	}
//
//	ret = redisAppendCommandArgv(redis, argv.size(), &argv[0], &arglen[0]);
//
//	if (ret != REDIS_OK)
//	{
//		redisFree(redis);
//		Reply reply;
//		reply.SetErrorMessage("Do Command faild.");
//		LOG(ERROR, "Do Command faild.");
//		return reply;
//	}
//
//	if (REDIS_OK != redisGetReply(redis, (void**) &reply))
//	{
//		redisFree(redis);
//		Reply reply;
//		reply.SetErrorMessage("Do Select Command faild.");
//		LOG(ERROR, "Do Select Command faild.");
//		return reply;
//	}
//
//	if (string(reply->str) != string("OK"))
//	{
//		redisFree(redis);
//		Reply reply;
//		reply.SetErrorMessage(
//				"Do Select Command faild, please check redis config parameter databases, it must >= 1024!");
//		LOG(ERROR, "Do Select Command faild, please check redis config parameter databases, it must >= 1024!");
//		exit(1);
//	}
//
//	if (REDIS_OK != redisGetReply(redis, (void**) &reply))
//	{
//		redisFree(redis);
//		Reply reply;
//		reply.SetErrorMessage("Do Command faild.");
//		LOG(ERROR, "Do Command faild.");
//		return reply;
//	}
//
//	m_ConnPool->returnItem(redis);
//	Reply retrep = Reply(reply);
//	freeReplyObject(reply);
//	return retrep;
}