redis(源码1):封装hiredis库,提供直观的C++函数操作

来源:互联网 发布:软件开发专业大学排名 编辑:程序博客网 时间:2024/04/30 09:03

最近抽时间把hiredis给封装了一下,便于编程,不用每次都查命令

redis命令查询地址:http://doc.redisfans.com/index.html

源码部分稍后会上传到资源包位置。




/*

* redis_interface.h
* Author: ws
* Data: 2015-12-24

*/


#ifndef REDIS_INTERFACE_H_
#define REDIS_INTERFACE_H_


#include <string>
#include <map>
#include <set>
#include <time.h>
#include <vector>


#include "hiredis/hiredis.h"
#include "../h/types.h"
#include "../h/mutex.h"


using namespace std;


namespace ws_redis
{
#define WS_REDIS_LOG_LENGTH_MAX 2048 // redis log最大长度
#define WS_REDIS_CONTEXT_HASH_MARK 5381 // redis连接hash查找掩码


//--------------------------------------------------------
// reids命令实行时间检测器
//--------------------------------------------------------
class RedisCmdTimeTesting
{
public:
RedisCmdTimeTesting();
virtual ~RedisCmdTimeTesting();
void Log(PRedisContext pRD, const char* fmt, ...); // cmd执行命令log


private:
std::string m_log; // 日志
timeval m_begin;// 起始时间
timeval m_end;// 结束时间
};


//--------------------------------------------------------
// reids 执行报告记录器
//--------------------------------------------------------
struct RedisReport_t
{
uint32_t m_State;// 报告状态0表示关闭,1表示开启
uint32_t m_Pid;// 监控线程pid
uint32_t m_RunCount;// 执行总数
uint64_t m_RunTime;// 执行时间(所有语句执行的时间和)
uint64_t m_StartTime;// 起始时间
map<std::string, map<std::string,uint32_t> >m_KeyInfo; // 同一条语句执行的次数和时间<key,<"time"/"count",>>
RedisReport_t() :m_State(0), m_Pid(0), m_RunCount(0), m_StartTime(0)
{
m_KeyInfo.clear();
}
};


struct SortData
{
std::string m_number;//对应sortedSet的member
std::string m_score;//对应sortedSet的score
};


//--------------------------------------------------------
// reids 连接管理器
//--------------------------------------------------------
class RedisManager
{
public:
static RedisManager & Instence(void)
{
static RedisManager obj;
return obj;
}
public:
// -----------------redis连接相关---------------------
uint32_t CreateContext(std::string ip, uint32_t port);// 创建链接
uint32_t CreateContextWithOutTime(std::string ip, uint32_t port, uint32_t time); // 建立链接,带超时时间
bool CloseContext(uint32_t index_link);// 指定管理某个链接
bool CloseAllContext();// 关闭所有链接
PRedisContext getRedis(std::string key);// 根据key获取redis连接(多连接情况下)通过hash key找到该key存储的redis连接,并发情况下可以提高并发率
PRedisContext getRedis(uint32_t index_link);// 直接指明hashmap中第几个redis连接
bool selectDB(PRedisContext& pRD, uint32_t index_db);// 获取指定redis连接中的第N个DB


// -----------------tool工具--------------------------
std::string contextAddrInfo(PRedisContext& pRD);// 链接信息
std::string replayInfo(redisReply* pReply);// 报告信息
std::string replaceCmdCrlf(const char* format);// 将命令中的一些符号替换掉




// -----------------redis命令相关---------------------
redisReply* redisCommand(PRedisContext& pRD, const char *format, ...);
// key
bool getAllKeys(PRedisContext& pRD, set<std::string>& value, std::string strMatching = "*");// (消耗性能)获取数据库中所有的key;  value: 为返回的所有key集合, strMatching:为查找匹配,默认为"*"所有,可以为如"t[w]*"表达式
bool isKeyExist(PRedisContext& pRD, const string& key, bool& keyExist);// 检查key是否存在
bool delKey(PRedisContext& pRD, const std::string& key);// 删除指定的key
bool keyType(PRedisContext& pRD, const std::string& key, std::string& type);// 获取key的类型;返回值:none(key不存在),std::string(字符串),list(列表),set(集合),zset(有序集),hash(哈希表)
bool setKeyTTL(PRedisContext& pRD, const std::string& key, uint32_t time);// 设置key的生存时间,单位s
bool expireAt(PRedisContext& pRD, const std::string& key, time_t calTime);// 更新key的生存时间, 单位time;
uint32_t delKey_T(PRedisContext& pRD, const std::string& key);// 事务模式:删除指定的key, 返回0表示失败, 1表示成功, 2表示存入队列(因为有事务处理)


// lock 模拟,阻塞(最大阻塞2秒)
bool lock(PRedisContext& pRD, const std::string &key, uint32_t ttl);// 加锁
bool unlock(PRedisContext& pRD, const std::string &key);// 解锁


//--- string
bool setStrValue(PRedisContext& pRD, const std::string& key, const std::string& value);// 设置key-value
bool setStrValue(PRedisContext& pRD, const std::string& key, const std::string& value, const uint32_t& time);// 设置key-value,带时间
bool getStrValue(PRedisContext& pRD, const std::string& key, std::string& value);// 获取key-value
bool setAnyValue(PRedisContext &pRD, map<std::string, std::string> value);// 一次插入多个值
bool getAnyValue(PRedisContext& pRD, const set<std::string>& setKeys, map<std::string, std::string>& outMapInfo); // 一次获取多个数据的值
bool incrValue(PRedisContext& pRD, const std::string& key, int incrNum = 1);// 每次增加指定值,默认为1
bool incrValue(PRedisContext& pRD, const std::string& key, long long &outValue, int incrNum = 1);// 每次增加指定值,默认为1,返回增加后的值
bool decrValue(PRedisContext& pRD, const std::string& key, int decrNum = 1);// 每次减去指定值,默认为1
bool decrValue(PRedisContext& pRD, const std::string& key, long long &outValue, int decrNum = 1);// 每次减去指定值,默认为1,返回增加后的值


//--- list
bool getListLen(PRedisContext& pRD, const std::string& key, uint32_t& len);// 获取list长度
bool lPushList(PRedisContext& pRD, const std::string& key, std::string& value);// 插入表头,表为空创建
bool rPushList(PRedisContext& pRD, const std::string& key, std::string& value);// 插入表尾,表为空创建
bool lPushXList(PRedisContext& pRD, const std::string& key, std::string& value);// 插入表头,表为空不创建
bool rPushXList(PRedisContext& pRD, const std::string& key, std::string& value);// 插入表尾,表为空创建
bool lPushAnyList(PRedisContext& pRD, const std::string& key, vector<std::string>& values);// 插入多个值到表头,先插入数据在表尾
bool rPushAnyList(PRedisContext& pRD, const std::string& key, vector<std::string>& values);// 插入多个值到表尾,先插入数据在表头
bool lPushGetLen(PRedisContext& pRD, const std::string& key, std::string& value, uint32_t& len);// 插入表头并获取长度
bool rPushGetLen(PRedisContext& pRD, const std::string& key, std::string& value, uint32_t& len);// 插入表尾并获取长度
bool rPushListBit(PRedisContext& pRD, const std::string& key, std::string& binMem);// (二进制)插入单个字符列到list尾部,如"a b c"
bool lPopListBit(PRedisContext& pRD, const std::string& key, std::string& binMem, bool& keyExist);// (二进制)移除字符列, keyExist 判断是否获取字符
bool rPopList(PRedisContext& pRD, const std::string& key, std::string& value, bool& keyExist);// 移除表尾的元素
bool lPopList(PRedisContext& pRD, const std::string& key, std::string& value, bool& keyExist);// 移除表头的元素
bool lremList(PRedisContext& pRD, const std::string& key, std::string& value, std::string count = "1"); // 移除与value值相同的元素,count为移除个数(正数表示从前到后移除n个,负数表示从后往前移除n个,0表示移除所有)
bool lrangeList(PRedisContext& pRD, const std::string& key, std::vector<std::string>& result, uint32_t startPos = 0, uint32_t endPos = 0); // 返回指定区域内的元素列表

//--- hash
bool setHashValue(PRedisContext& pRD, const std::string& key, std::string field, std::string strValue); // 设置hash值
bool getHashValue(PRedisContext& pRD, const std::string& key, std::string field, std::string& strValue);// 获取hash值
bool setAnyHashValue(PRedisContext& pRD, const std::string& key, map<std::string, std::string>& values);// 设置多个值
bool getAnyHashValue(PRedisContext& pRD, const std::string& key, vector<std::string>& fields, map<std::string, std::string>& values); // 获取多个值
bool getHashAllValue(PRedisContext& pRD, const std::string& key, map<std::string, std::string>& valueMap); // 获取所有hash值对
bool getHashAllFields(PRedisContext& pRD, const std::string& key, vector<std::string>& fields);// 获取目标key的所有field
bool setHashValueBit(PRedisContext& pRD, const std::string& key, std::string field, std::string binValue);// (二进制)设置hash值
bool getAnyHashValueBit(PRedisContext& pRD, const std::string& key, map<std::string, std::string>& valueMap);// (二进制)获取所有键值对
bool delHashValue(PRedisContext& pRD, const std::string& key, std::string field);// 删除hash值
bool delHashValue(PRedisContext& pRD, const std::string& key, const set<std::string> & fields, int64_t& rmCount);// 删除多个hash值
bool isMemInHash(PRedisContext& pRD, const std::string& key, std::string field, bool& isMem);// 判断是不是hash成员
bool incrHashValue(PRedisContext& pRD,const std::string& key, std::string field,std::string value = "1");// 在原始值上增加指定值
bool setHashValue_T(PRedisContext& pRD, const std::string& key, map<std::string, std::string>& fieldValue); // (事务) 设置hash值


//--- set
bool isMemInSet(PRedisContext& pRD, const std::string& key, std::string& value, bool& isMem);// 判断是不是set成员
bool getSetCount(PRedisContext& pRD, const std::string& key, uint32_t& count, bool& keyExist);// 获取set元素个数
bool setSetValue(PRedisContext& pRD, const std::string& key, std::string& value);// 添加元素,已经存在的元素被忽略
bool setAnySetValue(PRedisContext& pRD, const std::string& key, set<std::string>& value);// 添加多个值,已经存在的元素被忽略
bool getAnySetValue(PRedisContext& pRD, const std::string& key, set<std::string>& value);// 获取set集合
bool remSetValue(PRedisContext& pRD, const std::string& key, std::string& value);// 移除集合中的元素
bool remAnySetValue(PRedisContext& pRD, const std::string &key, const std::set<std::string> &value);// 移除多个指定元素
bool getSetSunion(PRedisContext& pRD, set<std::string>& keys, set<std::string>& value);// 获取多个key的并集
bool getSetSdiff(PRedisContext& pRD, set<std::string>& keys, set<std::string>& value);// 获取多个key的差集
bool getSetSinter(PRedisContext& pRD, set<std::string>& keys, set<std::string>& value);// 获取多个key的交集
bool setSetValue_T(PRedisContext& pRD, const std::string& key, std::string& value);// (事务)添加集合元素





// --- sortset
bool isMemInSortedSet(PRedisContext& pRD, const std::string& key, const std::string& member, bool& isMem); // 检查目标是不是sortset的资源
bool getCountSortedSet(PRedisContext& pRD, const std::string& key, uint32_t& totalCount);// 获取资源个数
bool setSortSet(PRedisContext& pRD, const std::string& key, std::string& mem, const uint64_t& score);// 添加元素到key
bool setAnySortSet(PRedisContext& pRD, const std::string& key, const map<std::string, std::string>& scores);// 添加多个元素到key
bool incrSortSet(PRedisContext& pRD, const std::string& key, const std::string& mem, const uint32_t& incrScore);// 给指定元素增加incrScore的值
bool decrScore(PRedisContext& pRD, const std::string& key, std::string& mem, const uint32_t& decrScore); //减少资源的排序值
bool remMemFromSortedSet(PRedisContext& pRD, const std::string& key, const std::string& mem);            // 删除指定资源
bool remRangeByScore(PRedisContext& pRD, const std::string& key, const uint32_t& min, const uint32_t& max); // 删除资源排序值域的资源
bool getScoreByMember(PRedisContext& pRD, const std::string& key, const std::string& member, uint32_t& score); // 返回指定资源的排序值(注意是值不是排名)
bool getDescRankByMember(PRedisContext& pRD, const std::string& key, const std::string& member, uint32_t& rank); // 获取资源的降序排名
bool getAscRankByMember(PRedisContext& pRD, const std::string& key, const std::string& member, uint32_t& rank); // 获取资源升序排名
bool incrSortSetBit(PRedisContext& pRD, const std::string& key, std::string& mem, const uint32_t& incrScore);  // (二进制)给指定元素增加incrScore的值
bool getDescSortedData(PRedisContext& pRD, const std::string& key, const uint32_t& offset, const uint32_t& limit, std::vector<SortData>& datas); // (降序)从大到小获取指定段的数据, 0 score 会被过滤掉
bool getDescSortedAllData(PRedisContext& pRD, const std::string& key, const uint32_t& offset, const uint32_t& limit, std::vector<SortData>& datas); // (降序)从大到小获取指定段的数据, 0 score 不会被过滤掉
   bool getAscSortedData(PRedisContext& pRC, const string& key, const uint32_t& start, const uint32_t& end, std::vector<SortData> &datas); // (升序)从小到大获取指定数据段的数据, 0 score 会被过滤掉
bool getAscSortedAllData(PRedisContext& pRD, const std::string& key, const uint32_t& start, const uint32_t& end, std::vector<SortData>& datas); // (升序)从小到大获取指定数据段的数据, 0 score 不会被过滤掉
bool setSortedSet_T(PRedisContext& pRD, const std::string& key, std::string& mem, const uint32_t& score); // (事务)添加元素
bool decrScore_T(PRedisContext& pRD, const std::string& key, std::string& mem, const uint32_t& decrScore); // (事务)删除资源
bool incrMemScore_T(PRedisContext& pRD, const std::string& key, std::string& mem, const uint32_t& incrScore); // (事务)添加资源值


// --- Transaction(事务)
bool beginTransaction(PRedisContext& pRD);// 开始事务,标记事务开始
bool endTransaction(PRedisContext& pRD, bool& isAborted);// 结束事务,执行所有事务
bool endTransaction(PRedisContext& pRD, bool& isAborted, redisReply** pReply);// 事务结束,执行所有事务 
bool discardTransaction(PRedisContext& pRD);// 取消事务(回滚),取消执行模块内的所有事务
bool watch(PRedisContext& pRD, const std::string& key);// 监控一个key
bool watch(PRedisContext& pRD, const vector<std::string>& keys);// 监控一些key
bool unwatch(PRedisContext& pRD);// 取消监控key




// --- lua 脚本控制
bool loadScript(PRedisContext& pRD, const std::string& key,const std::string& script);// 加载脚本,指定脚本对应一个key
bool existsScript(PRedisContext& pRD, const std::string& key);// 检查key指定的脚本是不是已经加载
bool getAllScriptKeys(PRedisContext& pRD);// 获取已经加载的所有的脚本key
bool clearAllScript(PRedisContext& pRD);// 清理所有已经加载的脚本缓存
bool exceScript(PRedisContext& pRD, const std::string& key, std::vector<std::string> &outValue);// 执行脚本,outValue表示返回数据
bool stopRuningScript(PRedisContext& pRD);// 终止当前正在执行的脚本(且当该脚本没有执行写操作才能成功)






// -----------------reids执行报告----------------------
// 初始化redis执行报告; pid:为0表示监视所有线程,其他表示单一线程
uint32_t startRedisReport(uint32_t pid = 0);
void stopRedisReport();// 关闭redis报告记录
std::string getRedisReport(); // 打印执行报告
void buildReport(std::string key, timeval startTime, timeval endTime); // 产生报告



private:
map<PRedisContext, map<string, string> > m_Script;// 脚本<key,脚本对应的校验和>
map<uint32_t, PRedisContext> m_allRedisConn; // 所有的redis连接
uint32_t m_MaxRedisContext;// redis最大连接个数
RedisReport_t m_RedisReport;// redis执行报告
ws::mutex m_RedisLock;// 线程锁
private:
RedisManager() {};
};




#define REDIS_MANAGER RedisManager::Instence()


}




#endif /* REDIS_INTERFACE_H_ */
1 0