#ifndef _MY_REDIS_POOL_HPP_
#define _MY_REDIS_POOL_HPP_
#include <cstdio>
#include <cstdlib>
#include <string>
#include <time.h>
#include <vector>
#include <queue>
#include<mutex>
#include <hiredis/hiredis.h>
#ifdef _WIN32
//编译 hiredis 会生成这2个库
#pragma comment(lib, "hiredis.lib")
#pragma comment(lib,"Win32_Interop.lib")
#endif // _WIN32
typedef struct RedisNode
{
int id;
redisContext *c;
bool isUsed;
};
class MyRedisPool
{
public:
static MyRedisPool& GetInstance();
protected:
MyRedisPool();
~MyRedisPool();
private:
MyRedisPool(const MyRedisPool& rhs) {}
MyRedisPool& operator = (const MyRedisPool& rhs) {}
public:
bool InitConnect(std::string const& host, std::string const& password, int port,int count);
RedisNode& GetConnect(bool& isSuccess);
bool GetRedisReply(redisReply *&reply);
bool AddConnect();
bool DisConnect();
bool BackConnect(RedisNode& node);
bool GetLPOP(std::string const&key, std::string&value, int dbName);
bool SetLPUSH(std::string const&key, std::string&value, int dbName);
bool GetLRange(std::string const&key, int dbName, int start, int end, std::vector<std::string>& result);
bool SetString(std::string const&key, std::string&value, int dbName);
bool GetString(std::string const&key, std::string&value, int dbName);
bool SetInt(std::string const&key, int &number, int dbName);
bool GetInt(std::string const&key, int &number, int dbName);
bool SUBSCRIBE(std::string const&theme);
bool PUBLISH(std::string const& theme, std::string const& content);
bool GetLPOPByPipeline(std::string const&key, std::string&value, int dbName);
bool SetLPUSHByPipeline(std::string const&key, std::string&value, int dbName);
bool GetLRangeByPipeline(std::string const&key, int dbName, int start, int end, std::vector<std::string>& result);
bool SetStringByPipeline(std::string const&key, std::string&value, int dbName);
bool GetStringByPipeline(std::string const&key, std::string&value, int dbName);
bool SetIntByPipeline(std::string const&key, int &number, int dbName);
bool GetIntByPipeline(std::string const&key, int &number, int dbName);
protected:
bool CreateOneConnect(redisContext *&c);
private:
std::string m_Host;
int m_Port;
std::string m_PassWord;
int m_MaxConnects;
int m_CurConnects;
std::vector<RedisNode> m_RedisVec;
std::queue<int> m_QueueId;
std::mutex m_Lock;
std::mutex m_PrintLock;
bool m_runing;
};
MyRedisPool::MyRedisPool()
{
m_runing = true;
}
MyRedisPool::~MyRedisPool()
{
DisConnect();
printf("析构了...\n");
}
bool MyRedisPool::GetRedisReply(redisReply *&reply)
{
if (reply)
{
if (reply->type == REDIS_REPLY_ERROR)
{
std::lock_guard<std::mutex> lck(m_PrintLock);
fprintf(stderr, "error: %s\n", reply->str);
freeReplyObject(reply);
return false;
}
else
{
return true;
}
}
else
{
return false;
}
}
bool MyRedisPool::GetLPOPByPipeline(std::string const&key, std::string&value, int dbName)
{
bool isSuccess = false;
bool ret = false;
RedisNode &node = GetConnect(isSuccess);
if (isSuccess)
{
redisAppendCommand(node.c, "SELECT %d", dbName);
redisAppendCommand(node.c, "LPOP %s", key.data());
redisReply *reply = NULL;
redisGetReply(node.c,(void**)&reply);
ret = GetRedisReply(reply);
if (ret)
{
freeReplyObject(reply);
redisGetReply(node.c, (void**)&reply);
ret = GetRedisReply(reply);
if (ret)
{
value = reply->str;
freeReplyObject(reply);
}
}
BackConnect(node);
}
}
bool MyRedisPool::SetLPUSHByPipeline(std::string const&key, std::string&value, int dbName)
{
bool isSuccess = false;
bool ret = false;
RedisNode &node = GetConnect(isSuccess);
if (isSuccess)
{
redisAppendCommand(node.c, "SELECT %d", dbName);
redisAppendCommand(node.c, "LPUSH %s %s", key.data(), value.data());
redisReply *reply = NULL;
redisGetReply(node.c, (void**)&reply);
ret = GetRedisReply(reply);
if (ret)
{
freeReplyObject(reply);
redisGetReply(node.c, (void**)&reply);
ret = GetRedisReply(reply);
if (ret)
{