void ProducerStateTable::del(string key, string op /*= DEL_COMMAND*/, string prefix) { // Assembly redis command args into a string vector vector<string> args; args.push_back("EVALSHA"); args.push_back(m_shaDel); args.push_back("3"); args.push_back(getChannelName()); args.push_back(getKeySetName()); args.push_back(getKeyName(key)); args.push_back("G"); args.push_back(key); args.push_back("''"); // Transform data structure vector<const char *> args1; transform(args.begin(), args.end(), back_inserter(args1), [](const string &s) { return s.c_str(); } ); // Invoke redis command RedisCommand command; command.formatArgv((int)args1.size(), &args1[0], NULL); m_pipe->push(command, REDIS_REPLY_NIL); if (!m_buffered) { m_pipe->flush(); } }
void ProducerStateTable::set(string key, vector<FieldValueTuple> &values, string op /*= SET_COMMAND*/, string prefix) { // Assembly redis command args into a string vector vector<string> args; args.push_back("EVALSHA"); args.push_back(m_shaSet); args.push_back(to_string(values.size() + 2)); args.push_back(getChannelName()); args.push_back(getKeySetName()); args.insert(args.end(), values.size(), getKeyName(key)); args.push_back("G"); args.push_back(key); for (auto& iv: values) { args.push_back(fvField(iv)); args.push_back(fvValue(iv)); } // Transform data structure vector<const char *> args1; transform(args.begin(), args.end(), back_inserter(args1), [](const string &s) { return s.c_str(); } ); // Invoke redis command RedisCommand command; command.formatArgv((int)args1.size(), &args1[0], NULL); m_pipe->push(command, REDIS_REPLY_NIL); if (!m_buffered) { m_pipe->flush(); } }
void Table::dump(TableDump& tableDump) { SWSS_LOG_ENTER(); // note that this function is not efficient // it can take ~100ms for entire asic dump // but it's not intended to be efficient // since it will not be used many times static std::string luaScript = loadLuaScript("table_dump.lua"); static std::string sha = m_pipe->loadRedisScript(luaScript); SWSS_LOG_TIMER("getting"); RedisCommand command; command.format("EVALSHA %s 1 %s ''", sha.c_str(), getTableName().c_str()); RedisReply r = m_pipe->push(command, REDIS_REPLY_STRING); auto ctx = r.getContext(); std::string data = ctx->str; json j = json::parse(data); size_t tableNameLen = getTableName().length() + 1; // + ":" for (json::iterator it = j.begin(); it != j.end(); ++it) { TableMap map; json jj = it.value(); for (json::iterator itt = jj.begin(); itt != jj.end(); ++itt) { if (itt.key() == "NULL") { continue; } map[itt.key()] = itt.value(); } std::string key = it.key().substr(tableNameLen); tableDump[key] = map; } }
void Table::set(string key, vector<FieldValueTuple> &values, string /*op*/, string /*prefix*/) { if (values.size() == 0) return; RedisCommand cmd; cmd.formatHMSET(getKeyName(key), values); m_pipe->push(cmd, REDIS_REPLY_STATUS); if (!m_buffered) { m_pipe->flush(); } }
RedisReply::RedisReply(DBConnector *db, const RedisCommand& command, int expectedType) : RedisReply(db, command) { guard([&]{checkReplyType(expectedType);}, command.c_str()); }
RedisReply::RedisReply(DBConnector *db, const RedisCommand& command) { redisAppendFormattedCommand(db->getContext(), command.c_str(), command.length()); redisGetReply(db->getContext(), (void**)&m_reply); guard([&]{checkReply();}, command.c_str()); }
void ConsumerStateTable::pops(std::deque<KeyOpFieldsValuesTuple> &vkco, std::string /*prefix*/) { static std::string luaScript = "local ret = {}\n" "local keys = redis.call('SPOP', KEYS[1], ARGV[1])\n" "local n = table.getn(keys)\n" "for i = 1, n do\n" "local key = keys[i]\n" "local values = redis.call('HGETALL', KEYS[2] .. key)\n" "table.insert(ret, {key, values})\n" "end\n" "return ret\n"; static std::string sha = loadRedisScript(m_db, luaScript); RedisCommand command; command.format( "EVALSHA %s 2 %s %s: %d ''", sha.c_str(), getKeySetName().c_str(), getTableName().c_str(), POP_BATCH_SIZE); RedisReply r(m_db, command); auto ctx0 = r.getContext(); vkco.clear(); // if the set is empty, return an empty kco object if (ctx0->type == REDIS_REPLY_NIL) { return; } assert(ctx0->type == REDIS_REPLY_ARRAY); size_t n = ctx0->elements; vkco.resize(n); for (size_t ie = 0; ie < n; ie++) { auto& kco = vkco[ie]; auto& values = kfvFieldsValues(kco); assert(values.empty()); auto& ctx = ctx0->element[ie]; assert(ctx->elements == 2); assert(ctx->element[0]->type == REDIS_REPLY_STRING); std::string key = ctx->element[0]->str; kfvKey(kco) = key; assert(ctx->element[1]->type == REDIS_REPLY_ARRAY); auto ctx1 = ctx->element[1]; for (size_t i = 0; i < ctx1->elements / 2; i++) { FieldValueTuple e; fvField(e) = ctx1->element[i * 2]->str; fvValue(e) = ctx1->element[i * 2 + 1]->str; values.push_back(e); } // if there is no field-value pair, the key is already deleted if (values.empty()) { kfvOp(kco) = DEL_COMMAND; } else { kfvOp(kco) = SET_COMMAND; } } }