Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Executing HMSET command with hiredis

Tags:

c++

redis

hiredis

I want to put a std::map<std::string, std::string> into redis server with hiredis. Since the API only allows formatted strings to be passed to redisCommand, I'm unable to store the map via a single command. I've tried using pipelines, but that is slower than HMSET and is therefore not applicable to performance restrains I'm in.

Anyone knows of any direct or indirect methods to pass a variant sized map via hiredis?

like image 250
Klaus Avatar asked Mar 15 '23 01:03

Klaus


1 Answers

You are supposed to use the "Argv" flavors of redisCommand:

int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);

You need to build two arrays (pointers and sizes) before they can be called.

Something like this should work (untested):

void hmset( redisContext *c, const string &key, const map<string,string> &m )
{
  vector<const char *> argv;
  vector<size_t> argvlen;

  static char cmd[] = "HMSET";
  argv.push_back( cmd );
  argvlen.push_back( sizeof(cmd)-1 );

  argv.push_back( key.c_str() );
  argvlen.push_back( key.size() );

  map<string,string>::const_iterator i;
  for ( i=m.begin(); i!=m.end(); ++i )
  {
    argv.push_back( i->first.c_str() );
    argvlen.push_back( i->first.size() );
    argv.push_back( i->second.c_str() );
    argvlen.push_back( i->second.size() );
  }

  void *r = redisCommandArgv(c, argv.size(), &(argv[0]), &(argvlen[0]) );
  if ( !r )
    throw runtime_error( "Redis error" );
  freeReplyObject( r );
}

Note that if your map contains a lot of items, it is a wrong idea to push it to Redis in one single command. Past N=100-1000 items, variadic commands should be split (in batches of N items) and pipelined. Keep in mind that Redis is single-threaded. When a huge command is executed, nothing else is executed. Plus, you can hit the limit of the communication buffer.

like image 113
Didier Spezia Avatar answered Mar 24 '23 08:03

Didier Spezia