Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions common/rediscommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,18 @@ void RedisCommand::formatHDEL(const std::string& key, const std::vector<std::str
formatArgv(static_cast<int>(args.size()), args.data(), NULL);
}

/* Format EXPIRE key field command */
void RedisCommand::formatEXPIRE(const std::string& key, const int64_t& ttl)
{
return format("EXPIRE %s %lld", key.c_str(), ttl);
}

/* Format TTL key command */
void RedisCommand::formatTTL(const std::string& key)
{
return format("TTL %s", key.c_str());
}

const char *RedisCommand::c_str() const
{
return temp;
Expand Down
6 changes: 6 additions & 0 deletions common/rediscommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ class RedisCommand {
/* Format HDEL key multiple fields command */
void formatHDEL(const std::string& key, const std::vector<std::string>& fields);

/* Format EXPIRE key ttl command */
void formatEXPIRE(const std::string& key, const int64_t& ttl);

/* Format TTL key command */
void formatTTL(const std::string& key);

const char *c_str() const;

size_t length() const;
Expand Down
39 changes: 37 additions & 2 deletions common/table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,21 +123,56 @@ void Table::hset(const string &key, const std::string &field, const std::string
}

void Table::set(const string &key, const vector<FieldValueTuple> &values,
const string& /*op*/, const string& /*prefix*/)
const string &op, const string &prefix)
{
set(key, values, op, prefix, DEFAULT_DB_TTL);
}

// TODO: Implement this without overloading(add an additional ttl param
// to existing set() command once sonic-swss's mock_table.cpp and other
// dependencies can be updated to use the extended new default set())
void Table::set(const string &key, const vector<FieldValueTuple> &values,
const string &op, const string &prefix, const int64_t &ttl)
{
if (values.size() == 0)
return;

RedisCommand cmd;

cmd.formatHMSET(getKeyName(key), values.begin(), values.end());

m_pipe->push(cmd, REDIS_REPLY_STATUS);

if (ttl != DEFAULT_DB_TTL)
{
// Configure the expire time for the entry that was just added
cmd.formatEXPIRE(getKeyName(key), ttl);
m_pipe->push(cmd, REDIS_REPLY_INTEGER);
}

if (!m_buffered)
{
m_pipe->flush();
}
}

bool Table::ttl(const string &key, int64_t &reply_value)
{
RedisCommand cmd_ttl;
cmd_ttl.formatTTL(getKeyName(key));
RedisReply r = m_pipe->push(cmd_ttl);
redisReply *reply = r.getContext();

if (reply != NULL)
{
reply_value = reply->integer;
return true;
}
else
{
return false;
}
}

void Table::del(const string &key, const string& /* op */, const string& /*prefix*/)
{
RedisCommand del_key;
Expand Down
13 changes: 13 additions & 0 deletions common/table.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ class TableEntryEnumerable {
void getContent(std::vector<KeyOpFieldsValuesTuple> &tuples);
};

/* The default time to live for a DB entry is infinite */
static constexpr int64_t DEFAULT_DB_TTL = -1;

class Table : public TableBase, public TableEntryEnumerable {
public:
Table(const DBConnector *db, const std::string &tableName);
Expand All @@ -175,10 +178,20 @@ class Table : public TableBase, public TableEntryEnumerable {
const std::vector<FieldValueTuple> &values,
const std::string &op = "",
const std::string &prefix = EMPTY_PREFIX);

/* Set an entry in the DB directly and configure ttl for it (op not in use) */
virtual void set(const std::string &key,
Copy link
Copy Markdown
Contributor

@qiluo-msft qiluo-msft Sep 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set

You should treat this overload function as a mimic of original set function with another optional parameter. So please only add ttl paramter at the end. Then op and prefix will be non-optional in this overload function. #Closed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I will update it accordingly

const std::vector<FieldValueTuple> &values,
const std::string &op,
const std::string &prefix,
const int64_t &ttl);

/* Delete an entry in the table */
virtual void del(const std::string &key,
const std::string &op = "",
const std::string &prefix = EMPTY_PREFIX);
/* Get the configured ttl value for key */
bool ttl(const std::string &key, int64_t &reply_value);

#ifdef SWIG
// SWIG interface file (.i) globally rename map C++ `del` to python `delete`,
Expand Down
44 changes: 44 additions & 0 deletions tests/redis_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,50 @@ TEST(Table, table_separator_test)
TableBasicTest("TABLE_UT_TEST", false);
}

TEST(Table, ttl_test)
{
string tableName = "TABLE_UT_TEST";
DBConnector db("TEST_DB", 0, true);
RedisPipeline pipeline(&db);
Table t(&pipeline, tableName, true);

clearDB();
cout << "Starting table manipulations" << endl;

string key_1 = "a";
string key_2 = "b";
vector<FieldValueTuple> values;

for (int i = 1; i < 4; i++)
{
string field = "field_" + to_string(i);
string value = to_string(i);
values.push_back(make_pair(field, value));
}

int64_t initial_a_ttl = -1, initial_b_ttl = 200;
cout << "- Step 1. SET with custom ttl" << endl;
cout << "Set key [a] field_1:1 field_2:2 field_3:3 infinite ttl" << endl;
cout << "Set key [b] field_1:1 field_2:2 field_3:3 200 seconds ttl" << endl;

t.set(key_1, values, "", "", initial_a_ttl);
t.set(key_2, values, "", "", initial_b_ttl);
t.flush();

cout << "- Step 2. GET_TTL_VALUES" << endl;

int64_t a_ttl = 0, b_ttl = 0;
// Expect that we find the two entries confgured in the DB
EXPECT_EQ(true, t.ttl(key_1, a_ttl));
EXPECT_EQ(true, t.ttl(key_2, b_ttl));

// Expect that TTL values are the ones configured earlier
EXPECT_EQ(a_ttl, initial_a_ttl);
EXPECT_EQ(b_ttl, initial_b_ttl);

cout << "Done." << endl;
}

TEST(ProducerConsumer, Prefix)
{
std::string tableName = "tableName";
Expand Down