设为首页 加入收藏

TOP

C++ Redis mset 二进制数据接口封装方案(一)
2015-07-20 17:19:51 来源: 作者: 【 】 浏览:8
Tags:Redis mset 二进制数据 接口 封装 方案
内容目录:
?
需求
简单拼接方案
redisCommandArgv接口传递 方案
redisCommandArgv接口传递的Vector方案
二进制校验
参考资料
C++ Redis mset 二进制数据接口封装方案
?
需求
?
C++中使用hiredis客户端接口访问redis;?
需要使用mset一次设置多个二进制数据
?
以下给出三种封装实现方案;
?
简单拼接方案
?
在redis-cli中,mset的语法是这样的:
?
/opt/colin$./redis-cli mset a 11 b 22 c 333
OK
按照这样的语法拼接后,直接使用hiredis字符串接口redisCommand传递:
?
void msetNotBinary(redisContext *c, const vector &vtKey, const vector & vtVal )
{
? ? if(vtKey.size() != vtVal.size())
? ? {
? ? ? ? throw runtime_error( "Redis error" );
? ? }
?
? ? string strCmd = "MSET";
? ? for(int i = 0; i < vtKey.size(); i++)
? ? {
? ? ? ? strCmd += " "+vtKey[i]+" "+vtVal[i];
? ? }
? ? cout << "strCmd:" << strCmd << endl;
?
? ? void * r = ?redisCommand(c, strCmd.c_str() );
? ? if ( !r )
? ? ? ? throw runtime_error( "Redis error" );
? ? freeReplyObject( r );
}
?
void do_test( redisContext *c )
{ ? ?
? ? vector vtKey;
? ? vector vtVal;
?
? ? vtKey.push_back("A");
? ? vtVal.push_back("AAAA");
? ? vtKey.push_back("B");
? ? vtVal.push_back("BBBB");
? ? vtKey.push_back("C");
? ? vtVal.push_back("CCCC");
? ? //add a binary data
? ? vtKey.push_back("D");
? ? vtVal.push_back("");
? ? char a[] = "ABCDE";
? ? a[2] = 0;
? ? vtVal[3].assign(a,5);
?
? ? try
? ? {
? ? ? ? msetNotBinary(c, vtKey, vtVal );
? ? ? ? //mset1( c, vtKey, vtVal );
? ? ? ? //mset2( c, vtKey, vtVal );
? ? }
? ? catch ( runtime_error & )
? ? {
? ? ? ? cout << "Error" << endl;
? ? }
}
?
int main(int argc, char *argv[])
{
? ? redisContext *c;
?
? ? c = redisConnect("127.0.0.1",6379);
? ? if (c->err)
? ? ?{
? ? ? ? cout << "Connection error: " << c->errstr << endl;
? ? ? ? return -1;
? ? }
?
? ? do_test(c);
?
? ? redisFree(c);
?
? ? return 0;
}
这种方式可以处理mset多个字符串数据,但对于数据内容为二进制数据的无能为力;
?
redisCommandArgv接口传递 方案
?
对于多个参数传递,hiredis提供了以下接口,这个接口中最后一个参数是所有的传入数据的内容长度,?
就是说这个接口是二进制安全的:
?
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
主要工作就是构造一个动态的二维数组char ** argv,其中涉及到char **到const char **的转换,有一定的风险,?
关于这一点前一篇文章已经谈到;
?
void mset1( redisContext *c, const vector &vtKey, const vector & vtVal )
{
? ? if(vtKey.size() != vtVal.size())
? ? {
? ? ? ? throw runtime_error( "Redis error" );
? ? }
?
? ? char ** argv = new char*[vtKey.size() + vtVal.size() + 1 ];
? ? size_t * argvlen = new size_t[vtKey.size() + vtVal.size() + 1 ];
?
? ? int j = 0;
? ? argv[j] = new char[5];
? ? memcpy(argv[j],"MSET",4);
? ? argvlen[j] = 4;
? ? ++j;
?
?
? ? for(int i = 0 ; i < vtKey.size();i++)
? ? { ? ?
? ? ? ? argvlen[j] = vtKey[i].length();
? ? ? ? argv[j] = new char[argvlen[j]];
? ? ? ? ?memset((void*)argv[j],0,argvlen[j] );
? ? ? ? memcpy((void*)argv[j],vtKey[i].data(),vtKey[i].length());
? ? ? ? j++;
?
? ? ? ? argvlen[j] = vtVal[i].length();
? ? ? ? argv[j] = new char[argvlen[j]];
? ? ? ? memset((void*)argv[j],0,argvlen[j]);
? ? ? ? memcpy((void*)argv[j],vtVal[i].data(),vtVal[i].length());
? ? ? ? j++;
? ? }
?
? ? //if not use const_cast ,compile error
? ? //for why assign from char** to const char** error, see my blog ...
? ? ?void *r = redisCommandArgv(c, vtKey.size() + vtVal.size() + 1, const_cast(argv), argvlen );
? ? if ( !r )
? ? ? ? throw runtime_error( "Redis error" );
? ? freeReplyObject( r );
?
? ? for(int i = 0;i < vtKey.size();i++)
? ? {
? ? ? ? delete [] argv[i];
? ? ? ? argv[i] = NULL;
? ? }
?
? ? delete []argv;
? ? delete []arg
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Leetcode_Factorial Trailing Zer.. 下一篇poj3239 Solution to the n Queen..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·C/C++ 类模板与模板 (2025-12-27 01:49:52)
·C语言 模板化<templ (2025-12-27 01:49:49)
·C/C++模板类模板与函 (2025-12-27 01:49:46)
·如何理解c语言指针和 (2025-12-27 01:19:11)
·为什么C标准库没有链 (2025-12-27 01:19:08)