std::map<std::string, std::string>
ハイレディスでredisサーバーに入れたいです。API では書式設定された文字列のみを に渡すことができるため、redisCommand
1 つのコマンドでマップを保存することはできません。パイプラインを使用してみましたが、それはより遅いため、現在HMSET
のパフォーマンスの制約には適用できません。
バリアントサイズのマップをhiredis経由で渡す直接的または間接的な方法を知っている人はいますか?
std::map<std::string, std::string>
ハイレディスでredisサーバーに入れたいです。API では書式設定された文字列のみを に渡すことができるため、redisCommand
1 つのコマンドでマップを保存することはできません。パイプラインを使用してみましたが、それはより遅いため、現在HMSET
のパフォーマンスの制約には適用できません。
バリアントサイズのマップをhiredis経由で渡す直接的または間接的な方法を知っている人はいますか?
redisCommand の「Argv」フレーバーを使用することになっています。
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);
呼び出す前に、2 つの配列 (ポインターとサイズ) を作成する必要があります。
このようなものは動作するはずです(テストされていません):
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 );
}
マップに多くのアイテムが含まれている場合、単一のコマンドでそれを Redis にプッシュするのは間違った考えであることに注意してください。N=100-1000 アイテムを超えると、可変長コマンドは (N アイテムのバッチで) 分割され、パイプライン化される必要があります。Redis はシングルスレッドであることに注意してください。巨大なコマンドが実行されると、それ以外は何も実行されません。さらに、通信バッファの限界に達する可能性があります。