Skip to content

Commit

Permalink
[orchagent] orchagent: Adding capablility of working with several tables
Browse files Browse the repository at this point in the history
* Modified Orch classes to be able to hold several ConsumerTable classes

Signed-off-by: Hrachya Mughnetsyan [email protected]
  • Loading branch information
Hrachya Mughnetsyan authored and Shuotian Cheng committed Apr 19, 2016
1 parent 36b7791 commit 2a4cc2a
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 106 deletions.
22 changes: 11 additions & 11 deletions orchagent/intfsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ IntfsOrch::IntfsOrch(DBConnector *db, string tableName, PortsOrch *portsOrch) :
{
}

void IntfsOrch::doTask()
void IntfsOrch::doTask(Consumer &consumer)
{
SWSS_LOG_ENTER();

if (m_toSync.empty())
if (consumer.m_toSync.empty())
return;

auto it = m_toSync.begin();
while (it != m_toSync.end())
auto it = consumer.m_toSync.begin();
while (it != consumer.m_toSync.end())
{
KeyOpFieldsValuesTuple t = it->second;

Expand All @@ -35,15 +35,15 @@ void IntfsOrch::doTask()
if (found == string::npos)
{
SWSS_LOG_ERROR("Failed to parse task key %s\n", key.c_str());
it = m_toSync.erase(it);
it = consumer.m_toSync.erase(it);
continue;
}
string alias = key.substr(0, found);

IpPrefix ip_prefix(key.substr(found+1));
if (!ip_prefix.isV4())
{
it = m_toSync.erase(it);
it = consumer.m_toSync.erase(it);
continue;
}

Expand All @@ -54,15 +54,15 @@ void IntfsOrch::doTask()
/* Duplicate entry */
if (m_intfs.find(alias) != m_intfs.end() && m_intfs[alias] == ip_prefix.getIp())
{
it = m_toSync.erase(it);
it = consumer.m_toSync.erase(it);
continue;
}

Port p;
if (!m_portsOrch->getPort(alias, p))
{
SWSS_LOG_ERROR("Failed to locate interface %s\n", alias.c_str());
it = m_toSync.erase(it);
it = consumer.m_toSync.erase(it);
continue;
}

Expand Down Expand Up @@ -112,7 +112,7 @@ void IntfsOrch::doTask()
{
SWSS_LOG_NOTICE("Create packet action trap route ip:%s\n", ip_prefix.getIp().to_string().c_str());
m_intfs[alias] = ip_prefix.getIp();
it = m_toSync.erase(it);
it = consumer.m_toSync.erase(it);
}
}
else if (op == DEL_COMMAND)
Expand All @@ -121,7 +121,7 @@ void IntfsOrch::doTask()
if (!m_portsOrch->getPort(alias, p))
{
SWSS_LOG_ERROR("Failed to locate interface %s\n", alias.c_str());
it = m_toSync.erase(it);
it = consumer.m_toSync.erase(it);
continue;
}

Expand Down Expand Up @@ -154,7 +154,7 @@ void IntfsOrch::doTask()
{
SWSS_LOG_NOTICE("Remove packet action trap route ip:%s\n", ip_prefix.getIp().to_string().c_str());
m_intfs.erase(alias);
it = m_toSync.erase(it);
it = consumer.m_toSync.erase(it);
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions orchagent/intfsorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ class IntfsOrch : public Orch
public:
IntfsOrch(DBConnector *db, string tableName, PortsOrch *portsOrch);
private:
void doTask();

PortsOrch *m_portsOrch;
IntfsTable m_intfs;
void doTask(Consumer &consumer);
};

#endif /* SWSS_INTFSORCH_H */
28 changes: 14 additions & 14 deletions orchagent/neighorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
extern sai_neighbor_api_t* sai_neighbor_api;
extern sai_next_hop_api_t* sai_next_hop_api;

void NeighOrch::doTask()
void NeighOrch::doTask(Consumer &consumer)
{
SWSS_LOG_ENTER();

if (m_toSync.empty())
if (consumer.m_toSync.empty())
return;

auto it = m_toSync.begin();
while (it != m_toSync.end())
auto it = consumer.m_toSync.begin();
while (it != consumer.m_toSync.end())
{
KeyOpFieldsValuesTuple t = it->second;

Expand All @@ -22,22 +22,22 @@ void NeighOrch::doTask()
if (found == string::npos)
{
SWSS_LOG_ERROR("Failed to parse task key %s\n", key.c_str());
it = m_toSync.erase(it);
it = consumer.m_toSync.erase(it);
continue;
}
string alias = key.substr(0, found);
Port p;

if (!m_portsOrch->getPort(alias, p))
{
it = m_toSync.erase(it);
it = consumer.m_toSync.erase(it);
continue;
}

IpAddress ip_address(key.substr(found+1));
if (!ip_address.isV4())
{
it = m_toSync.erase(it);
it = consumer.m_toSync.erase(it);
continue;
}

Expand All @@ -58,30 +58,30 @@ void NeighOrch::doTask()
if (m_syncdNeighbors.find(neighbor_entry) == m_syncdNeighbors.end() || m_syncdNeighbors[neighbor_entry] != mac_address)
{
if (addNeighbor(neighbor_entry, mac_address))
it = m_toSync.erase(it);
it = consumer.m_toSync.erase(it);
else
it++;
}
else
it = m_toSync.erase(it);
it = consumer.m_toSync.erase(it);
}
else if (op == DEL_COMMAND)
{
if (m_syncdNeighbors.find(neighbor_entry) != m_syncdNeighbors.end())
{
if (removeNeighbor(neighbor_entry))
it = m_toSync.erase(it);
it = consumer.m_toSync.erase(it);
else
it++;
}
/* Cannot locate the neighbor */
else
it = m_toSync.erase(it);
it = consumer.m_toSync.erase(it);
}
else
{
SWSS_LOG_ERROR("Unknown operation type %s\n", op.c_str());
it = m_toSync.erase(it);
it = consumer.m_toSync.erase(it);
}
}
}
Expand Down Expand Up @@ -147,8 +147,8 @@ bool NeighOrch::addNeighbor(NeighborEntry neighborEntry, MacAddress macAddress)
}
else
{
// XXX: The neighbor entry is already there
// XXX: MAC change
// TODO: The neighbor entry is already there
// TODO: MAC change
}

return true;
Expand Down
3 changes: 1 addition & 2 deletions orchagent/neighorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,13 @@ typedef map<NeighborEntry, MacAddress> NeighborTable;
class NeighOrch : public Orch
{
public:

NeighOrch(DBConnector *db, string tableName, PortsOrch *portsOrch, RouteOrch *routeOrch) :
Orch(db, tableName), m_portsOrch(portsOrch), m_routeOrch(routeOrch) {};
private:
PortsOrch *m_portsOrch;
RouteOrch *m_routeOrch;

void doTask();
void doTask(Consumer &consumer);

NeighborTable m_syncdNeighbors;

Expand Down
88 changes: 64 additions & 24 deletions orchagent/orch.cpp
Original file line number Diff line number Diff line change
@@ -1,68 +1,108 @@
#include "orch.h"

#include "logger.h"

using namespace swss;

Orch::Orch(DBConnector *db, string tableName) :
m_db(db), m_name(tableName)
m_db(db)
{
m_consumer = new ConsumerTable(m_db, tableName);
Consumer consumer(new ConsumerTable(m_db, tableName));
m_consumerMap.insert(ConsumerMapPair(tableName, consumer));
}

Orch::Orch(DBConnector *db, vector<string> &tableNames) :
m_db(db)
{
for( auto it = tableNames.begin(); it != tableNames.end(); it++) {
Consumer consumer(new ConsumerTable(m_db, *it));
m_consumerMap.insert(ConsumerMapPair(*it, consumer));
}
}

Orch::~Orch()
{
delete(m_db);
delete(m_consumer);
for(auto it : m_consumerMap) {
delete it.second.m_consumer;
}
}

void Orch::execute()
std::vector<Selectable*> Orch::getConsumers()
{
SWSS_LOG_ENTER();

KeyOpFieldsValuesTuple t;
m_consumer->pop(t);
std::vector<Selectable*> consumers;
for(auto it : m_consumerMap) {
consumers.push_back(it.second.m_consumer);
}
return consumers;
}

bool Orch::hasConsumer(ConsumerTable *consumer) const
{
for(auto it : m_consumerMap) {
if(it.second.m_consumer == consumer) {
return true;
}
}
return false;
}

bool Orch::execute(string tableName)
{
auto consumer_it = m_consumerMap.find(tableName);
if(consumer_it == m_consumerMap.end()) {
SWSS_LOG_ERROR("Unrecognized tableName:%s\n", tableName.c_str());
return false;
}
Consumer& consumer = consumer_it->second;

KeyOpFieldsValuesTuple new_data;
consumer.m_consumer->pop(new_data);

string key = kfvKey(t);
string op = kfvOp(t);
string key = kfvKey(new_data);
string op = kfvOp(new_data);

#ifdef DEBUG
string debug = "Orch : " + m_name + " key : " + kfvKey(t) + " op : " + kfvOp(t);
for (auto i = kfvFieldsValues(t).begin(); i != kfvFieldsValues(t).end(); i++)
string debug = "Table : " + consumer.m_consumer.getTableName() + " key : " + kfvKey(new_data) + " op : " + kfvOp(new_data);
for (auto i = kfvFieldsValues(new_data).begin(); i != kfvFieldsValues(new_data).end(); i++)
debug += " " + fvField(*i) + " : " + fvValue(*i);
SWSS_LOG_DEBUG("%s\n", debug.c_str());
#endif

/* If a new task comes or if a DEL task comes, we directly put it into m_toSync map */
if ( m_toSync.find(key) == m_toSync.end() || op == DEL_COMMAND)
/* If a new task comes or if a DEL task comes, we directly put it into consumer.m_toSync map */
if ( consumer.m_toSync.find(key) == consumer.m_toSync.end() || op == DEL_COMMAND)
{
m_toSync[key] = t;
consumer.m_toSync[key] = new_data;
}
/* If an old task is still there, we combine the old task with new task */
else
{
KeyOpFieldsValuesTuple u = m_toSync[key];
KeyOpFieldsValuesTuple existing_data = consumer.m_toSync[key];

auto tt = kfvFieldsValues(t);
auto uu = kfvFieldsValues(u);
auto new_values = kfvFieldsValues(new_data);
auto existing_values = kfvFieldsValues(existing_data);


for (auto it = tt.begin(); it != tt.end(); it++)
for (auto it = new_values.begin(); it != new_values.end(); it++)
{
string field = fvField(*it);
string value = fvValue(*it);

auto iu = uu.begin();
while (iu != uu.end())
auto iu = existing_values.begin();
while (iu != existing_values.end())
{
string ofield = fvField(*iu);
if (field == ofield)
iu = uu.erase(iu);
iu = existing_values.erase(iu);
else
iu++;
}
uu.push_back(FieldValueTuple(field, value));
existing_values.push_back(FieldValueTuple(field, value));
}
m_toSync[key] = KeyOpFieldsValuesTuple(key, op, uu);
consumer.m_toSync[key] = KeyOpFieldsValuesTuple(key, op, existing_values);
}

doTask();
doTask(consumer);
return true;
}
27 changes: 17 additions & 10 deletions orchagent/orch.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,35 @@ extern "C" {
using namespace std;
using namespace swss;

typedef map<string, KeyOpFieldsValuesTuple> SyncMap;
struct Consumer {
Consumer(ConsumerTable* consumer) :m_consumer(consumer) { }
ConsumerTable* m_consumer;
/* Store the latest 'golden' status */
SyncMap m_toSync;
};
typedef std::pair<string, Consumer> ConsumerMapPair;
typedef map<string, Consumer> ConsumerMap;

class Orch
{
public:
Orch(DBConnector *db, string tableName);
Orch(DBConnector *db, vector<string> &tableNames);
~Orch();

inline ConsumerTable *getConsumer() { return m_consumer; }

void execute();
virtual void doTask() = 0;
std::vector<Selectable*> getConsumers();
bool hasConsumer(ConsumerTable* s)const;

inline string getOrchName() { return m_name; }
bool execute(string tableName);

protected:
virtual void doTask(Consumer &consumer) = 0;
private:
DBConnector *m_db;
const string m_name;

protected:
ConsumerTable *m_consumer;

/* Store the latest 'golden' status */
map<string, KeyOpFieldsValuesTuple> m_toSync;
ConsumerMap m_consumerMap;

};

Expand Down
Loading

0 comments on commit 2a4cc2a

Please sign in to comment.