LCOV - code coverage report
Current view: top level - ifmap - ifmap_agent_table.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 0 381 0.0 %
Date: 2026-06-22 02:21:21 Functions: 0 29 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include "ifmap/ifmap_agent_table.h"
       6             : 
       7             : #include <boost/algorithm/string.hpp>
       8             : #include <boost/bind/bind.hpp>
       9             : #include <boost/format.hpp>
      10             : #include "base/logging.h"
      11             : #include "db/db.h"
      12             : #include "db/db_graph.h"
      13             : #include "db/db_table_partition.h"
      14             : #include "ifmap/ifmap_agent_parser.h"
      15             : #include "ifmap/ifmap_node.h"
      16             : #include "ifmap/ifmap_link.h"
      17             : #include "ifmap/ifmap_agent_types.h"
      18             : 
      19             : using namespace std;
      20             : using namespace boost::placeholders;
      21             : 
      22             : SandeshTraceBufferPtr
      23             : IFMapAgentTraceBuf(SandeshTraceBufferCreate("IFMapAgentTrace", 1000));
      24             : 
      25           0 : IFMapAgentTable::IFMapAgentTable(DB *db, const string &name, DBGraph *graph)
      26           0 :         : IFMapTable(db, name, graph), pre_filter_(NULL) {
      27           0 : }
      28             : 
      29           0 : unique_ptr<DBEntry> IFMapAgentTable::AllocEntry(const DBRequestKey *key) const {
      30             :     unique_ptr<DBEntry> entry(
      31           0 :         new IFMapNode(const_cast<IFMapAgentTable *>(this)));
      32           0 :     entry->SetKey(key);
      33           0 :     return entry;
      34           0 : }
      35             : 
      36           0 : IFMapNode* IFMapAgentTable::TableEntryLookup(DB *db, RequestKey *key) {
      37             : 
      38           0 :     IFMapTable *table = FindTable(db, key->id_type);
      39           0 :     if (!table) {
      40           0 :         return NULL;
      41             :     }
      42             : 
      43           0 :     unique_ptr<DBEntry> entry(new IFMapNode(table));
      44           0 :     entry->SetKey(key);
      45           0 :     IFMapNode *node = static_cast<IFMapNode *>(table->Find(entry.get()));
      46           0 :     return node;
      47           0 : }
      48             : 
      49             : 
      50           0 : IFMapAgentTable* IFMapAgentTable::TableFind(const string &node_name) {
      51           0 :     string name = node_name;
      52           0 :     std::replace(name.begin(), name.end(), '-', '_');
      53           0 :     name = "__ifmap__." + name + ".0";
      54             :     IFMapAgentTable *table =
      55           0 :             static_cast<IFMapAgentTable *>(database()->FindTable(name));
      56           0 :     return table;
      57           0 : }
      58             : 
      59           0 : IFMapNode *IFMapAgentTable::EntryLookup(RequestKey *request) {
      60           0 :     unique_ptr<DBEntry> key(AllocEntry(request));
      61           0 :     IFMapNode *node = static_cast<IFMapNode *>(Find(key.get()));
      62           0 :     return node;
      63           0 : }
      64             : 
      65           0 : IFMapNode *IFMapAgentTable::EntryLocate(IFMapNode *node, RequestKey *req) {
      66             : 
      67             :     IFMapObject *obj;
      68             : 
      69           0 :     if (node != NULL) {
      70             :         /* If delete marked, clear it now */
      71           0 :         if (node->IsDeleted()) {
      72           0 :             node->ClearDelete();
      73           0 :             graph()->AddNode(node);
      74             :         }
      75             : 
      76           0 :         obj = node->GetObject();
      77           0 :         assert(obj);
      78             :         //We dont accept lesser sequence number updates
      79           0 :         assert(obj->sequence_number() <= req->id_seq_num);
      80             : 
      81           0 :         node->Remove(obj);
      82             : 
      83             :     } else {
      84           0 :         unique_ptr<DBEntry> key(AllocEntry(req));
      85             :         node = const_cast<IFMapNode *>(
      86           0 :             static_cast<const IFMapNode *>(key.release()));
      87             :         DBTablePartition *partition =
      88           0 :             static_cast<DBTablePartition *>(GetTablePartition(0));
      89           0 :         partition->Add(node);
      90           0 :         graph()->AddNode(node);
      91           0 :     }
      92             : 
      93           0 :     return node;
      94             : }
      95             : 
      96             : // A node is deleted. Move all links for the node to defer-list
      97           0 : void IFMapAgentTable::HandlePendingLinks(IFMapNode *node) {
      98             : 
      99             :     IFMapNode *right;
     100             :     DBGraphEdge *edge;
     101             : 
     102             :     IFMapAgentLinkTable *ltable = static_cast<IFMapAgentLinkTable *>
     103           0 :         (database()->FindTable(IFMAP_AGENT_LINK_DB_NAME));
     104           0 :     assert(ltable != NULL);
     105             : 
     106           0 :     DBGraphVertex::edge_iterator iter;
     107             :     bool origin_exists;
     108             :     uint64_t seq;
     109           0 :     for (iter = node->edge_list_begin(graph());
     110           0 :          iter != node->edge_list_end(graph());) {
     111           0 :         edge = iter.operator->();
     112           0 :         IFMapLink *l = static_cast<IFMapLink *>(edge);
     113           0 :         right = static_cast<IFMapNode *>(iter.target());
     114           0 :         iter++;
     115           0 :         seq = l->sequence_number(IFMapOrigin::UNKNOWN, &origin_exists);
     116           0 :         assert(origin_exists);
     117             :         // Create both the request keys
     118           0 :         unique_ptr <IFMapAgentLinkTable::RequestKey> req_key (new IFMapAgentLinkTable::RequestKey);
     119           0 :         req_key->left_key.id_name = node->name();
     120           0 :         req_key->left_key.id_type = node->table()->Typename();
     121           0 :         req_key->left_key.id_seq_num = seq;
     122             : 
     123           0 :         req_key->right_key.id_name = right->name();
     124           0 :         req_key->right_key.id_type = right->table()->Typename();
     125           0 :         req_key->right_key.id_seq_num = seq;
     126           0 :         req_key->metadata = l->metadata();
     127             : 
     128           0 :         DBRequest req;
     129           0 :         req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
     130           0 :         req.key = std::move(req_key);
     131             : 
     132             :         //Add it to defer list
     133           0 :         ltable->LinkDefAdd(&req);
     134             : 
     135           0 :         ltable->DelLink(node, right, edge);
     136           0 :     }
     137           0 : }
     138             : 
     139           0 : void IFMapAgentTable::DeleteNode(IFMapNode *node) {
     140             : 
     141             : 
     142           0 :     if ((node->HasAdjacencies(graph()) == true)) {
     143           0 :         HandlePendingLinks(node);
     144             :     }
     145             : 
     146             :     //Now there should not be any more adjacencies
     147           0 :     assert((node->HasAdjacencies(graph()) == false));
     148             : 
     149             :     DBTablePartition *partition =
     150           0 :         static_cast<DBTablePartition *>(GetTablePartition(0));
     151           0 :     graph()->RemoveNode(node);
     152           0 :     partition->Delete(node);
     153           0 : }
     154             : 
     155           0 : void IFMapAgentTable::NotifyNode(IFMapNode *node) {
     156             :     DBTablePartition *partition =
     157           0 :         static_cast<DBTablePartition *>(GetTablePartition(0));
     158           0 :     partition->Change(node);
     159           0 : }
     160             : 
     161             : // Process link-defer list based for the request.
     162             : // If request is add, create left->right and right-left defer nodes
     163             : // If request is delete, remove left->right and right->left defer nodes
     164             : // The sequence number is valid only in the DeferrendNode entry
     165           0 : void IFMapAgentLinkTable::LinkDefAdd(DBRequest *request) {
     166           0 :     RequestKey *key = static_cast<RequestKey *>(request->key.get());
     167             : 
     168           0 :     std::list<DeferredNode>::iterator it;
     169             : 
     170           0 :     std::list<DeferredNode> *left = NULL;
     171           0 :     LinkDefMap::iterator left_it = link_def_map_.find(key->left_key);
     172           0 :     if (link_def_map_.end() != left_it)
     173           0 :         left = left_it->second;
     174             : 
     175           0 :     std::list<DeferredNode> *right = NULL;
     176           0 :     LinkDefMap::iterator right_it = link_def_map_.find(key->right_key);
     177           0 :     if (link_def_map_.end() != right_it)
     178           0 :         right = right_it->second;
     179             : 
     180           0 :     if (request->oper == DBRequest::DB_ENTRY_DELETE)  {
     181             :         //We need to delete the old sequence links as well
     182             :         // remove left->right entry
     183           0 :         if (left) {
     184           0 :             for(it = left->begin(); it != left->end(); it++) {
     185           0 :                 if (((*it).node_key.id_type == key->right_key.id_type) &&
     186           0 :                     ((*it).node_key.id_name == key->right_key.id_name)) {
     187           0 :                     left->erase(it);
     188           0 :                     break;
     189             :                 }
     190             :             }
     191           0 :             RemoveDefListEntry(&link_def_map_, left_it, NULL);
     192             :         }
     193             : 
     194             :         // remove right->left entry
     195           0 :         if (right) {
     196           0 :             for(it = right->begin(); it != right->end(); it++) {
     197           0 :                 if (((*it).node_key.id_type == key->left_key.id_type) &&
     198           0 :                     ((*it).node_key.id_name == key->left_key.id_name)) {
     199           0 :                     right->erase(it);
     200           0 :                     break;
     201             :                 }
     202             :             }
     203           0 :             RemoveDefListEntry(&link_def_map_, right_it, NULL);
     204             :         }
     205             : 
     206           0 :         return;
     207             :     }
     208             : 
     209           0 :     bool push_left = true;
     210             : 
     211             :     // Add/Update left->right entry
     212           0 :     if (left) {
     213             :         // If list already contains, just update the seq number
     214           0 :         for(it = left->begin(); it != left->end(); it++) {
     215           0 :             if (((*it).node_key.id_type == key->right_key.id_type) &&
     216           0 :                     ((*it).node_key.id_name == key->right_key.id_name)) {
     217           0 :                 (*it).node_key.id_seq_num = key->right_key.id_seq_num;
     218           0 :                 (*it).link_metadata = key->metadata;
     219           0 :                 push_left = false;
     220           0 :                 break;
     221             :             }
     222             :         }
     223             :     } else {
     224           0 :         left = new std::list<DeferredNode>();
     225           0 :         link_def_map_[key->left_key] = left;
     226             :     }
     227             : 
     228           0 :     bool push_right = true;
     229             :     // Add/Update right->left entry
     230           0 :     if (right) {
     231             :         // If list already contains, just update the seq number
     232           0 :         for(it = right->begin(); it != right->end(); it++) {
     233           0 :             if (((*it).node_key.id_type == key->left_key.id_type) &&
     234           0 :                     ((*it).node_key.id_name == key->left_key.id_name)) {
     235           0 :                 (*it).node_key.id_seq_num = key->left_key.id_seq_num;
     236           0 :                 (*it).link_metadata = key->metadata;
     237           0 :                 push_right = false;
     238           0 :                 break;
     239             :             }
     240             :         }
     241             :     } else {
     242           0 :         right = new std::list<DeferredNode>();
     243           0 :         link_def_map_[key->right_key] = right;
     244             :     }
     245             : 
     246             :     // Add it to the end of the list
     247           0 :     struct DeferredNode dn;
     248           0 :     dn.link_metadata = key->metadata;
     249           0 :     if (push_left) {
     250           0 :         dn.node_key = key->right_key;
     251           0 :         left->push_back(dn);
     252             :     }
     253           0 :     if (push_right) {
     254           0 :         dn.node_key = key->left_key;
     255           0 :         right->push_back(dn);
     256             :     }
     257           0 :     return;
     258           0 : }
     259             : 
     260           0 : void IFMapAgentTable::Input(DBTablePartition *partition, DBClient *client,
     261             :                              DBRequest *request) {
     262           0 :     RequestKey *key = static_cast<RequestKey *>(request->key.get());
     263           0 :     IFMapAgentTable *table = NULL;
     264             :     struct IFMapAgentData *req_data;
     265             :     IFMapObject *obj;
     266             : 
     267           0 :     table = TableFind(key->id_type);
     268           0 :     if (!table) {
     269           0 :         IFMAP_AGENT_TRACE(Trace, key->id_seq_num,
     270             :                 "Table " + key->id_type + " not found");
     271           0 :         return;
     272             :     }
     273             : 
     274           0 :     IFMapNode *node = EntryLookup(key);
     275           0 :     if (table->pre_filter_) {
     276           0 :         DBRequest::DBOperation old_oper = request->oper;
     277           0 :         if (table->pre_filter_(table, node, request) == false) {
     278           0 :             IFMAP_AGENT_TRACE(Trace, key->id_seq_num,
     279             :                     "Node " + key->id_name + " neglected as filter"
     280             :                     + "suppressed");
     281           0 :             return;
     282             :         }
     283           0 :         if ((old_oper != DBRequest::DB_ENTRY_DELETE) &&
     284           0 :                 (request->oper == DBRequest::DB_ENTRY_DELETE)) {
     285           0 :             IFMAP_AGENT_TRACE(Trace, key->id_seq_num,
     286             :                     "Node " + key->id_name + "ID_PERMS Null");
     287             :         }
     288             :     }
     289             : 
     290           0 :     if (request->oper == DBRequest::DB_ENTRY_DELETE) {
     291           0 :         if (node == NULL) {
     292           0 :             IFMAP_AGENT_TRACE(Trace, key->id_seq_num,
     293             :                     "Node " + key->id_name + " not found in Delete");
     294           0 :             return;
     295             :         }
     296             : 
     297           0 :         if (node->IsDeleted()) {
     298           0 :             IFMAP_AGENT_TRACE(Trace, key->id_seq_num,
     299             :                         "Node " + key->id_name + " already deleted");
     300           0 :             return;
     301             :         }
     302             : 
     303           0 :         obj = node->GetObject();
     304             :         //We dont accept lesser sequence number updates
     305           0 :         assert(obj->sequence_number() <= key->id_seq_num);
     306             : 
     307             :         //Upate the sequence number even for deletion of node
     308           0 :         obj->set_sequence_number(key->id_seq_num);
     309           0 :         DeleteNode(node);
     310           0 :         return;
     311             :     }
     312             : 
     313           0 :     if (request->oper == DBRequest::DB_ENTRY_NOTIFY) {
     314           0 :         if (node) {
     315           0 :             partition->Notify(node);
     316             :         }
     317           0 :         return;
     318             :     }
     319             : 
     320           0 :     node = EntryLocate(node, key);
     321           0 :     assert(node);
     322             : 
     323             :     //Get the data from request key and notify oper tables
     324           0 :     req_data = static_cast<struct IFMapAgentData *>(request->data.get());
     325           0 :     obj = static_cast<IFMapObject *>(req_data->content.release());
     326             : 
     327             :     //Set the sequence number of the object
     328           0 :     obj->set_sequence_number(key->id_seq_num);
     329             : 
     330           0 :     node->Insert(obj);
     331           0 :     NotifyNode(node);
     332             : 
     333             :     IFMapAgentLinkTable *link_table = static_cast<IFMapAgentLinkTable *>(
     334           0 :         database()->FindTable(IFMAP_AGENT_LINK_DB_NAME));
     335           0 :     link_table->EvalDefLink(key);
     336             : }
     337             : 
     338           0 : void IFMapAgentTable::Clear() {
     339           0 :     assert(!HasListeners());
     340             :     DBTablePartition *partition = static_cast<DBTablePartition *>(
     341           0 :         GetTablePartition(0));
     342           0 :     IFMapNode *next = NULL;
     343           0 :     for (IFMapNode *node = static_cast<IFMapNode *>(partition->GetFirst());
     344           0 :          node != NULL; node = next) {
     345           0 :         next = static_cast<IFMapNode *>(partition->GetNext(node));
     346           0 :         if (node->IsDeleted()) {
     347           0 :             continue;
     348             :         }
     349           0 :         graph()->RemoveNode(node);
     350           0 :         partition->Delete(node);
     351             :     }
     352           0 : }
     353             : 
     354             : 
     355             : // Agent link table routines
     356           0 : IFMapLink *IFMapAgentLinkTable::FindLink(IFMapNode *left, IFMapNode *right,
     357             :                                   const std::string &metadata) {
     358             : 
     359             :     IFMapLinkTable *table = static_cast<IFMapLinkTable *>(
     360           0 :         database()->FindTable(IFMAP_AGENT_LINK_DB_NAME));
     361           0 :     assert(table != NULL);
     362           0 :     IFMapLink *link = table->FindLink(metadata, left, right);
     363           0 :     return (link ? (link->IsDeleted() ? NULL : link) : NULL);
     364             : }
     365             : 
     366           0 : void IFMapAgentLinkTable::AddLink(IFMapNode *left, IFMapNode *right,
     367             :                                   const std::string &metadata,
     368             :                                   uint64_t seq) {
     369             : 
     370             :     IFMapLinkTable *table = static_cast<IFMapLinkTable *>(
     371           0 :         database()->FindTable(IFMAP_AGENT_LINK_DB_NAME));
     372           0 :     assert(table != NULL);
     373             : 
     374           0 :     IFMapLink *link = table->AddLink(left, right, metadata, seq,
     375           0 :                                      IFMapOrigin(IFMapOrigin::UNKNOWN));
     376           0 :     graph()->Link(left, right, (DBGraphEdge *)link);
     377           0 : }
     378             : 
     379           0 : void IFMapAgentLinkTable::DelLink(IFMapNode *left, IFMapNode *right, DBGraphEdge *edge) {
     380             :     IFMapAgentLinkTable *table = static_cast<IFMapAgentLinkTable *>(
     381           0 :         database()->FindTable(IFMAP_AGENT_LINK_DB_NAME));
     382           0 :     assert(table != NULL);
     383           0 :     table->DeleteLink(static_cast<IFMapLink *>(edge));
     384           0 : }
     385             : 
     386           0 : IFMapAgentLinkTable::IFMapAgentLinkTable(DB *db, const string &name, DBGraph *graph)
     387           0 :         : IFMapLinkTable(db, name, graph) {
     388           0 : }
     389             : 
     390           0 : DBTable *IFMapAgentLinkTable::CreateTable(DB *db, const string &name,
     391             :                                      DBGraph *graph) {
     392           0 :     IFMapAgentLinkTable *table = new IFMapAgentLinkTable(db, name, graph);
     393           0 :     table->Init();
     394           0 :     return table;
     395             : }
     396             : 
     397             : 
     398           0 : void IFMapAgentLinkTable_Init(DB *db, DBGraph *graph) {
     399           0 :     db->RegisterFactory(IFMAP_AGENT_LINK_DB_NAME,
     400             :         boost::bind(&IFMapAgentLinkTable::CreateTable, _1, _2, graph));
     401           0 :     db->CreateTable(IFMAP_AGENT_LINK_DB_NAME);
     402           0 : }
     403             : 
     404           0 : void IFMapAgentLinkTable::Input(DBTablePartition *partition, DBClient *client,
     405             :                            DBRequest *req) {
     406             : 
     407           0 :     RequestKey *key = static_cast<RequestKey *>(req->key.get());
     408             : 
     409             :     IFMapNode *left;
     410           0 :     left = IFMapAgentTable::TableEntryLookup(database(), &key->left_key);
     411           0 :     if (!left) {
     412           0 :         IFMAP_AGENT_TRACE(Trace, key->left_key.id_seq_num,
     413             :                 key->left_key.id_type + ":" + key->left_key.id_name +
     414             :                 " not present for link to " + key->right_key.id_type +
     415             :                 ":" + key->right_key.id_name);
     416           0 :         LinkDefAdd(req);
     417           0 :         return;
     418             :     }
     419             : 
     420             :     IFMapNode *right;
     421           0 :     right = IFMapAgentTable::TableEntryLookup(database(), &key->right_key);
     422           0 :     if (!right) {
     423           0 :         IFMAP_AGENT_TRACE(Trace, key->left_key.id_seq_num,
     424             :                 key->right_key.id_type + " : " + key->right_key.id_name +
     425             :                 " not present for link to " + key->left_key.id_type + " : " +
     426             :                 key->left_key.id_name);
     427           0 :         LinkDefAdd(req);
     428           0 :         return;
     429             :     }
     430             : 
     431           0 :     if (left->IsDeleted()) {
     432           0 :         IFMAP_AGENT_TRACE(Trace, key->left_key.id_seq_num,
     433             :             "Adding Link" + key->left_key.id_type + ":" +
     434             :             key->left_key.id_name + "->" + key->right_key.id_type +
     435             :                             ":" + key->right_key.id_name + " to defer "
     436             :                             "list as left is deleted marked");
     437           0 :         LinkDefAdd(req);
     438           0 :         return;
     439             :     }
     440             : 
     441           0 :     if (right->IsDeleted()) {
     442           0 :         IFMAP_AGENT_TRACE(Trace, key->left_key.id_seq_num,
     443             :             "Adding Link" + key->left_key.id_type + ":" +
     444             :             key->left_key.id_name + "->" + key->right_key.id_type +
     445             :                             ":" + key->right_key.id_name + " to defer "
     446             :                             "list as right is deleted marked");
     447           0 :         LinkDefAdd(req);
     448           0 :         return;
     449             :     }
     450             : 
     451           0 :     IFMapObject *obj = left->GetObject();
     452           0 :     if (obj->sequence_number() < key->left_key.id_seq_num) {
     453           0 :         IFMAP_AGENT_TRACE(Trace, key->left_key.id_seq_num,
     454             :             "IFMap Link " + left->name() + right->name() +
     455             :             " with wrong seq number");
     456           0 :         LinkDefAdd(req);
     457           0 :         return;
     458             :     }
     459             : 
     460           0 :     obj = right->GetObject();
     461           0 :     if (obj->sequence_number() < key->left_key.id_seq_num) {
     462           0 :         IFMAP_AGENT_TRACE(Trace, key->left_key.id_seq_num,
     463             :             "IFMap Link " + left->name() + right->name() +
     464             :             " with wrong seq number");
     465           0 :         LinkDefAdd(req);
     466           0 :         return;
     467             :     }
     468             : 
     469           0 :     DBGraphEdge *link = FindLink(left, right, key->metadata);
     470             : 
     471           0 :     if (req->oper == DBRequest::DB_ENTRY_ADD_CHANGE) {
     472           0 :         if (link == NULL) {
     473           0 :             AddLink(left, right, key->metadata, key->left_key.id_seq_num);
     474             :         } else {
     475           0 :             IFMapOrigin origin(IFMapOrigin::UNKNOWN);
     476           0 :             IFMapLink *l = static_cast<IFMapLink *>(link);
     477           0 :             l->UpdateProperties(origin, key->left_key.id_seq_num);
     478             :         }
     479             :     } else {
     480           0 :         if (link == NULL) {
     481           0 :             return;
     482             :         }
     483           0 :         DelLink(left, right, link);
     484             :     }
     485             : }
     486             : 
     487           0 : bool IFMapAgentLinkTable::RemoveDefListEntry
     488             :     (LinkDefMap *map, LinkDefMap::iterator &map_it,
     489             :      std::list<DeferredNode>::iterator *list_it) {
     490             : 
     491           0 :     std::list<DeferredNode> *list = map_it->second;
     492           0 :     if (list_it) {
     493           0 :         list->erase(*list_it);
     494             :     }
     495             : 
     496           0 :     if (list->size()) {
     497           0 :         return false;
     498             :     }
     499           0 :     map->erase(map_it);
     500           0 :     delete list;
     501           0 :     return true;
     502             : }
     503             : 
     504             : // For every link there are 2 entries,
     505             : //  left->right
     506             : //  right->left
     507             : //
     508             : //  If both left and right node are available, remove the entries and try to
     509             : //  add the link
     510           0 : void IFMapAgentLinkTable::EvalDefLink(IFMapTable::RequestKey *key) {
     511           0 :     LinkDefMap::iterator link_defmap_it = link_def_map_.find(*key);
     512           0 :     if (link_def_map_.end() == link_defmap_it)
     513           0 :         return;
     514             : 
     515           0 :     std::list<DeferredNode> *left_list = link_defmap_it->second;
     516           0 :     std::list<DeferredNode>::iterator left_it, left_list_entry;
     517           0 :     for(left_it = left_list->begin(); left_it != left_list->end();) {
     518           0 :         left_list_entry = left_it++;
     519             : 
     520             :         // If link seq is older, dont consider the link.
     521           0 :         if ((*left_list_entry).node_key.id_seq_num < key->id_seq_num)
     522           0 :             continue;
     523             : 
     524             :         // Skip if right-node is not yet present
     525           0 :         IFMapNode *node = IFMapAgentTable::TableEntryLookup(database(),
     526           0 :                     &((*left_list_entry).node_key));
     527           0 :         if (!node)
     528           0 :             continue;
     529             : 
     530             :         //If the other end of the node is not from active control node,
     531             :         //dont consider the link
     532           0 :         IFMapObject *obj = node->GetObject();
     533           0 :         if (obj->sequence_number() < key->id_seq_num)
     534           0 :             continue;
     535             : 
     536             : 
     537             :         // left->right entry found defer-list. Find the right->left entry
     538             :         LinkDefMap::iterator right_defmap_it =
     539           0 :             link_def_map_.find((*left_list_entry).node_key);
     540           0 :         assert(link_def_map_.end() != right_defmap_it);
     541             : 
     542           0 :         std::list<DeferredNode> *right_list = right_defmap_it->second;
     543           0 :         std::list<DeferredNode>::iterator right_it, right_list_entry;
     544           0 :         bool removed_something = false;
     545           0 :         for(right_it = right_list->begin(); right_it !=
     546           0 :                 right_list->end(); right_it++) {
     547             : 
     548             :             // If link seq is older, dont consider the link.
     549           0 :             if ((*right_it).node_key.id_seq_num < key->id_seq_num)
     550           0 :                 continue;
     551             : 
     552           0 :             if ((*right_it).node_key.id_type == key->id_type &&
     553           0 :                     (*right_it).node_key.id_name == key->id_name) {
     554           0 :                 RemoveDefListEntry(&link_def_map_, right_defmap_it, &right_it);
     555           0 :                 removed_something = true;
     556           0 :                 break;
     557             :             }
     558             :         }
     559             : 
     560             :         //We should have removed something in the above iteration
     561           0 :         assert(removed_something);
     562             : 
     563             :         //Remove from deferred list before enqueing
     564           0 :         unique_ptr <RequestKey> req_key (new RequestKey);
     565           0 :         req_key->left_key = *key;
     566           0 :         req_key->right_key = (*left_list_entry).node_key;
     567           0 :         req_key->metadata = (*left_list_entry).link_metadata;
     568             :         // Dont delete left_list_entry. Its passed in req structure
     569           0 :         left_list->erase(left_list_entry);
     570             : 
     571           0 :         DBRequest req;
     572           0 :         req.key = std::move(req_key);
     573           0 :         req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
     574           0 :         Enqueue(&req);
     575           0 :     }
     576             : 
     577             :     // If list does not have any entries, delete the list
     578           0 :     RemoveDefListEntry(&link_def_map_, link_defmap_it, NULL);
     579             : }
     580             : 
     581           0 : void IFMapAgentLinkTable::DestroyDefLink(uint64_t seq) {
     582             :     std::list<DeferredNode> *ent;
     583           0 :     std::list<DeferredNode>::iterator it, list_entry;
     584           0 :     IFMapAgentLinkTable::LinkDefMap::iterator dlist_it, temp;
     585             : 
     586           0 :     for(dlist_it = link_def_map_.begin(); dlist_it != link_def_map_.end(); ) {
     587           0 :         temp = dlist_it++;
     588           0 :         ent = temp->second;
     589           0 :         for(it = ent->begin(); it != ent->end();) {
     590           0 :             list_entry = it++;
     591             : 
     592             :             //Delete the deferred link if it is old seq
     593           0 :             if ((*list_entry).node_key.id_seq_num < seq) {
     594           0 :                 if (RemoveDefListEntry(&link_def_map_, temp,
     595           0 :                             &list_entry) == true) {
     596             :                     //The list has been deleted. Move to the next map
     597             :                     //entry
     598           0 :                     break;
     599             :                 }
     600             :             }
     601             :         }
     602             :     }
     603           0 : }
     604             : 
     605             : //Stale Cleaner functionality
     606             : class IFMapAgentStaleCleaner::IFMapAgentStaleCleanerWorker : public Task {
     607             : public:
     608             : 
     609           0 :     IFMapAgentStaleCleanerWorker(DB *db, DBGraph *graph, uint64_t seq):
     610             :         Task(TaskScheduler::GetInstance()->GetTaskId("db::DBTable"), 0),
     611           0 :         db_(db), graph_(graph), seq_(seq) {
     612           0 :     }
     613             : 
     614           0 :     bool Run() {
     615           0 :         IFMAP_AGENT_TRACE(Trace, seq_,
     616             :                 "IFMap Config Audit start:");
     617             :         //Handle the links first
     618           0 :         DBGraph::edge_iterator e_next(graph_);
     619           0 :         for (DBGraph::edge_iterator e_iter = graph_->edge_list_begin();
     620           0 :             e_iter != graph_->edge_list_end(); e_iter = e_next) {
     621             : 
     622           0 :             const DBGraph::DBEdgeInfo &tuple = *e_iter;
     623             : 
     624           0 :             e_next = ++e_iter;
     625             : 
     626           0 :             IFMapNode *lhs = static_cast<IFMapNode *>(boost::get<0>(tuple));
     627           0 :             IFMapNode *rhs = static_cast<IFMapNode *>(boost::get<1>(tuple));
     628           0 :             IFMapLink *link = static_cast<IFMapLink *>(boost::get<2>(tuple));
     629           0 :             assert(link);
     630             : 
     631           0 :             bool exists = false;
     632             :             IFMapLink::LinkOriginInfo origin_info =
     633           0 :                 link->GetOriginInfo(IFMapOrigin::UNKNOWN, &exists);
     634           0 :             if (exists && (origin_info.sequence_number < seq_ )) {
     635             :                 IFMapAgentLinkTable *ltable = static_cast<IFMapAgentLinkTable *>(
     636           0 :                     db_->FindTable(IFMAP_AGENT_LINK_DB_NAME));
     637           0 :                 IFMAP_AGENT_TRACE(Trace,
     638             :                      origin_info.sequence_number, "Deleting Link between " +
     639             :                      lhs->name() + rhs->name());
     640           0 :                 ltable->DeleteLink(link);
     641             :             }
     642             :         }
     643             : 
     644             :         //Handle the vertices now
     645           0 :         DBGraph::vertex_iterator v_next(graph_);
     646           0 :         for (DBGraph::vertex_iterator v_iter = graph_->vertex_list_begin();
     647           0 :             v_iter != graph_->vertex_list_end(); v_iter = v_next) {
     648             : 
     649           0 :             IFMapNode *node = static_cast<IFMapNode *>(v_iter.operator->());
     650           0 :             v_next = ++v_iter;
     651             : 
     652           0 :             IFMapObject *obj = node->GetObject();
     653           0 :             assert(obj);
     654           0 :             if (obj->sequence_number() < seq_) {
     655           0 :                 IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table());
     656           0 :                 IFMAP_AGENT_TRACE(Trace, obj->sequence_number(),
     657             :                         "Deleting node " + node->name());
     658           0 :                 table->DeleteNode(node);
     659             :             }
     660             :         }
     661             : 
     662             :         //Handle deferred list
     663             :         IFMapAgentLinkTable *table = static_cast<IFMapAgentLinkTable *>(
     664           0 :                     db_->FindTable(IFMAP_AGENT_LINK_DB_NAME));
     665           0 :         table->DestroyDefLink(seq_);
     666             : 
     667           0 :         return true;
     668             :     }
     669           0 :     std::string Description() const {
     670           0 :         return "IFMapAgentStaleCleaner::IFMapAgentStaleCleanerWorker";
     671             :     }
     672             : 
     673             : private:
     674             :     DB *db_;
     675             :     DBGraph *graph_;
     676             :     uint64_t seq_;
     677             : };
     678             : 
     679           0 : IFMapAgentStaleCleaner::~IFMapAgentStaleCleaner() {
     680           0 : }
     681             : 
     682           0 : IFMapAgentStaleCleaner::IFMapAgentStaleCleaner(DB *db, DBGraph *graph) :
     683           0 :         db_(db), graph_(graph) {
     684           0 : }
     685             : 
     686           0 : bool IFMapAgentStaleCleaner::StaleTimeout(uint64_t seq) {
     687           0 :     seq_ = seq;
     688           0 :     IFMapAgentStaleCleanerWorker *cleaner = new IFMapAgentStaleCleanerWorker(db_, graph_, seq_);
     689           0 :     TaskScheduler *sch = TaskScheduler::GetInstance();
     690           0 :     sch->Enqueue(cleaner);
     691           0 :     return false;
     692             : }
     693             : 
     694           0 : void IFMapAgentStaleCleaner::Clear() {
     695             :     IFMapLinkTable *table = static_cast<IFMapLinkTable *>(
     696           0 :         db_->FindTable(IFMAP_AGENT_LINK_DB_NAME));
     697           0 :     table->Clear();
     698           0 :     IFMapTable::ClearTables(db_);
     699           0 : }

Generated by: LCOV version 1.14