Skip to content

Commit

Permalink
common: Table: Adding set/get/del API
Browse files Browse the repository at this point in the history
In addition Table class provide a direct access to Redis DB.

The set() command writes to Redis using HSET command.
Usage:
    DBConnector db(0, "localhost", 6379, 0);
    Table t(&db1, "A_TABLE");

    FieldValueTuple a("field", "value");
    vector<FieldValueTuple> attrs = { a };

    t.set("key1", attrs);

The get() command read values using the HGETALL command.
Usage:
    vector<FieldValueTuple> v;
    if (!t.get("TEST", v))
    {
           cout << "not exists" << endl;
           return 0;
    }

    for(auto i : v)
    {
           cout << fvField(i) << " = " << fvValue(i) << endl;
    }

The del() command simply deletes an entry (Using DEL command)

portsyncd: Migrate to Table::get() API
  Move the check API to Table::get()
common: ProducerTable: Refactor API to use Table::formatHSET
common: ProducerTable: change set and del to inherit from Table APIs
common: ConsumerTable: Remove peek() API
  Remove peek() API, which is now Table::get() API

Signed-off-by: Elad Raz <eladr@mellanox.com>
  • Loading branch information
eladraz authored and Shuotian Cheng committed Mar 16, 2016
1 parent 930eff0 commit 805ebfe
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 46 deletions.
23 changes: 0 additions & 23 deletions common/consumertable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,29 +85,6 @@ void ConsumerTable::pop(KeyOpFieldsValuesTuple &kco)
kco = std::make_tuple(key, op, fieldsValues);
}

bool ConsumerTable::peek(std::string key, vector<FieldValueTuple> &values)
{
string hgetall_key("HGETALL ");
hgetall_key += getKeyName(key);

RedisReply r(m_db, hgetall_key, REDIS_REPLY_ARRAY);
redisReply *reply = r.getContext();
values.clear();

if (!reply->elements)
return false;

if (reply->elements & 1)
throw system_error(make_error_code(errc::address_not_available),
"Unable to connect netlink socket");

for (unsigned int i = 0; i < reply->elements; i += 2)
values.push_back(make_tuple(reply->element[i]->str,
reply->element[i + 1]->str));

return true;
}

void ConsumerTable::addFd(fd_set *fd)
{
FD_SET(m_subscribe->getContext()->fd, fd);
Expand Down
4 changes: 0 additions & 4 deletions common/consumertable.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ class ConsumerTable : public Table, public Selectable
/* Get a singlesubsribe channel rpop */
void pop(KeyOpFieldsValuesTuple &kco);

/* Get a key content without poping it from the notificaiton list */
/* return false if the key doesn't exists */
bool peek(std::string key, std::vector<FieldValueTuple> &values);

virtual void addFd(fd_set *fd);
virtual bool isMe(fd_set *fd);
virtual int readCache();
Expand Down
13 changes: 3 additions & 10 deletions common/producertable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,9 @@ void ProducerTable::set(string key, vector<FieldValueTuple> &values, string op)
{
multi();
for (FieldValueTuple &i : values)
{
char *temp;
int len = redisFormatCommand(&temp, "HSET %s %s %s",
getKeyName(key).c_str(),
fvField(i).c_str(),
fvValue(i).c_str());
string hset(temp, len);
free(temp);
enqueue(hset, REDIS_REPLY_INTEGER, true);
}
enqueue(formatHSET(getKeyName(key), fvField(i), fvValue(i)),
REDIS_REPLY_INTEGER, true);

enqueueDbChange(key, JSon::buildJson(values), op);
exec();
}
Expand Down
7 changes: 4 additions & 3 deletions common/producertable.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ class ProducerTable : public Table
public:
ProducerTable(DBConnector *db, std::string tableName);

void set(std::string key, std::vector<FieldValueTuple> &values,
std::string op = SET_COMMAND);
void del(std::string key, std::string op = DEL_COMMAND);
/* Implements set() and del() commands using notification messages */
virtual void set(std::string key, std::vector<FieldValueTuple> &values,
std::string op = SET_COMMAND);
virtual void del(std::string key, std::string op = DEL_COMMAND);

private:
/* Disable copy-constructor and operator = */
Expand Down
56 changes: 56 additions & 0 deletions common/table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,49 @@ string Table::getChannelTableName()
return m_tableName + "_CHANNEL";
}

bool Table::get(std::string key, vector<FieldValueTuple> &values)
{
string hgetall_key("HGETALL ");
hgetall_key += getKeyName(key);

RedisReply r(m_db, hgetall_key, REDIS_REPLY_ARRAY);
redisReply *reply = r.getContext();
values.clear();

if (!reply->elements)
return false;

if (reply->elements & 1)
throw system_error(make_error_code(errc::address_not_available),
"Unable to connect netlink socket");

for (unsigned int i = 0; i < reply->elements; i += 2)
values.push_back(make_tuple(reply->element[i]->str,
reply->element[i + 1]->str));

return true;
}

void Table::set(std::string key, std::vector<FieldValueTuple> &values,
std::string /*op*/)
{
/* We are doing transaction for AON (All or nothing) */
multi();
for (FieldValueTuple &i : values)
enqueue(formatHSET(getKeyName(key), fvField(i), fvValue(i)),
REDIS_REPLY_INTEGER, true);

exec();
}

void Table::del(std::string key, std::string /* op */)
{
RedisReply r(m_db, string("DEL ") + getKeyName(key), REDIS_REPLY_INTEGER);
if (r.getContext()->type != REDIS_REPLY_INTEGER)
throw system_error(make_error_code(errc::io_error),
"DEL operation failed");
}

void Table::multi()
{
while (!m_expectedResults.empty())
Expand Down Expand Up @@ -110,4 +153,17 @@ void Table::enqueue(std::string command, int exepectedResult, bool isFormatted)
m_expectedResults.push(exepectedResult);
}

string Table::formatHSET(const string& key, const string& field,
const string& value)
{
char *temp;
int len = redisFormatCommand(&temp, "HSET %s %s %s",
key.c_str(),
field.c_str(),
value.c_str());
string hset(temp, len);
free(temp);
return hset;
}

}
18 changes: 17 additions & 1 deletion common/table.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,20 @@ typedef std::tuple<std::string, std::string, std::vector<FieldValueTuple> > KeyO
#define kfvFieldsValues std::get<2>

class Table {
protected:
public:
Table(DBConnector *db, std::string tableName);

/* Read a value from the DB directly */
/* Returns false if the key doesn't exists */
bool get(std::string key, std::vector<FieldValueTuple> &values);

/* Set an entry in the DB directly (op not in used) */
virtual void set(std::string key, std::vector<FieldValueTuple> &values,
std::string op = "");
/* Delete an entry in the DB directly (op not in used) */
virtual void del(std::string key, std::string op = "");

protected:
/* Return the actual key name as a comibation of tableName:key */
std::string getKeyName(std::string key);

Expand All @@ -41,6 +52,11 @@ class Table {
redisReply* queueResultsFront();
void queueResultsPop();

/* Format HSET key field value command */
static std::string formatHSET(const std::string &key,
const std::string &field,
const std::string &value);

DBConnector *m_db;
std::string m_tableName;

Expand Down
6 changes: 3 additions & 3 deletions portsyncd/linksync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ void LinkSync::onMsg(int nlmsg_type, struct nl_object *obj)
fvVector.push_back(o);
fvVector.push_back(m);

if (m_lagTableConsumer.peek(key, temp))
if (m_lagTableConsumer.get(key, temp))
m_lagTableProducer.set(key, fvVector);
else if (m_vlanTableConsumer.peek(key, temp))
else if (m_vlanTableConsumer.get(key, temp))
m_vlanTableProducer.set(key, fvVector);
else if (m_portTableConsumer.peek(key, temp))
else if (m_portTableConsumer.get(key, temp))
m_portTableProducer.set(key, fvVector);
/* else discard managment or untracked netdev state */
}
3 changes: 1 addition & 2 deletions portsyncd/linksync.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#include "common/dbconnector.h"
#include "common/producertable.h"
#include "common/consumertable.h"
#include "common/netmsg.h"

namespace swss {
Expand All @@ -19,7 +18,7 @@ class LinkSync : public NetMsg

private:
ProducerTable m_portTableProducer, m_vlanTableProducer, m_lagTableProducer;
ConsumerTable m_portTableConsumer, m_vlanTableConsumer, m_lagTableConsumer;
Table m_portTableConsumer, m_vlanTableConsumer, m_lagTableConsumer;
};

}
Expand Down

0 comments on commit 805ebfe

Please sign in to comment.