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: 347 381 91.1 %
Date: 2026-08-17 02:09:53 Functions: 28 29 96.6 %
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         596 : IFMapAgentTable::IFMapAgentTable(DB *db, const string &name, DBGraph *graph)
      26         596 :         : IFMapTable(db, name, graph), pre_filter_(NULL) {
      27         596 : }
      28             : 
      29       14447 : unique_ptr<DBEntry> IFMapAgentTable::AllocEntry(const DBRequestKey *key) const {
      30             :     unique_ptr<DBEntry> entry(
      31       14447 :         new IFMapNode(const_cast<IFMapAgentTable *>(this)));
      32       14447 :     entry->SetKey(key);
      33       14447 :     return entry;
      34           0 : }
      35             : 
      36        7590 : IFMapNode* IFMapAgentTable::TableEntryLookup(DB *db, RequestKey *key) {
      37             : 
      38        7590 :     IFMapTable *table = FindTable(db, key->id_type);
      39        7590 :     if (!table) {
      40           0 :         return NULL;
      41             :     }
      42             : 
      43        7590 :     unique_ptr<DBEntry> entry(new IFMapNode(table));
      44        7590 :     entry->SetKey(key);
      45        7590 :     IFMapNode *node = static_cast<IFMapNode *>(table->Find(entry.get()));
      46        7590 :     return node;
      47        7590 : }
      48             : 
      49             : 
      50        3278 : IFMapAgentTable* IFMapAgentTable::TableFind(const string &node_name) {
      51        3278 :     string name = node_name;
      52        3278 :     std::replace(name.begin(), name.end(), '-', '_');
      53        3278 :     name = "__ifmap__." + name + ".0";
      54             :     IFMapAgentTable *table =
      55        3278 :             static_cast<IFMapAgentTable *>(database()->FindTable(name));
      56        3278 :     return table;
      57        3278 : }
      58             : 
      59        3278 : IFMapNode *IFMapAgentTable::EntryLookup(RequestKey *request) {
      60        3278 :     unique_ptr<DBEntry> key(AllocEntry(request));
      61        3278 :     IFMapNode *node = static_cast<IFMapNode *>(Find(key.get()));
      62        3278 :     return node;
      63        3278 : }
      64             : 
      65        1920 : IFMapNode *IFMapAgentTable::EntryLocate(IFMapNode *node, RequestKey *req) {
      66             : 
      67             :     IFMapObject *obj;
      68             : 
      69        1920 :     if (node != NULL) {
      70             :         /* If delete marked, clear it now */
      71         528 :         if (node->IsDeleted()) {
      72           0 :             node->ClearDelete();
      73           0 :             graph()->AddNode(node);
      74             :         }
      75             : 
      76         528 :         obj = node->GetObject();
      77         528 :         assert(obj);
      78             :         //We dont accept lesser sequence number updates
      79         528 :         assert(obj->sequence_number() <= req->id_seq_num);
      80             : 
      81         528 :         node->Remove(obj);
      82             : 
      83             :     } else {
      84        1392 :         unique_ptr<DBEntry> key(AllocEntry(req));
      85             :         node = const_cast<IFMapNode *>(
      86        1392 :             static_cast<const IFMapNode *>(key.release()));
      87             :         DBTablePartition *partition =
      88        1392 :             static_cast<DBTablePartition *>(GetTablePartition(0));
      89        1392 :         partition->Add(node);
      90        1392 :         graph()->AddNode(node);
      91        1392 :     }
      92             : 
      93        1920 :     return node;
      94             : }
      95             : 
      96             : // A node is deleted. Move all links for the node to defer-list
      97         111 : void IFMapAgentTable::HandlePendingLinks(IFMapNode *node) {
      98             : 
      99             :     IFMapNode *right;
     100             :     DBGraphEdge *edge;
     101             : 
     102             :     IFMapAgentLinkTable *ltable = static_cast<IFMapAgentLinkTable *>
     103         111 :         (database()->FindTable(IFMAP_AGENT_LINK_DB_NAME));
     104         111 :     assert(ltable != NULL);
     105             : 
     106         111 :     DBGraphVertex::edge_iterator iter;
     107             :     bool origin_exists;
     108             :     uint64_t seq;
     109         111 :     for (iter = node->edge_list_begin(graph());
     110         266 :          iter != node->edge_list_end(graph());) {
     111         155 :         edge = iter.operator->();
     112         155 :         IFMapLink *l = static_cast<IFMapLink *>(edge);
     113         155 :         right = static_cast<IFMapNode *>(iter.target());
     114         155 :         iter++;
     115         155 :         seq = l->sequence_number(IFMapOrigin::UNKNOWN, &origin_exists);
     116         155 :         assert(origin_exists);
     117             :         // Create both the request keys
     118         155 :         unique_ptr <IFMapAgentLinkTable::RequestKey> req_key (new IFMapAgentLinkTable::RequestKey);
     119         155 :         req_key->left_key.id_name = node->name();
     120         155 :         req_key->left_key.id_type = node->table()->Typename();
     121         155 :         req_key->left_key.id_seq_num = seq;
     122             : 
     123         155 :         req_key->right_key.id_name = right->name();
     124         155 :         req_key->right_key.id_type = right->table()->Typename();
     125         155 :         req_key->right_key.id_seq_num = seq;
     126         155 :         req_key->metadata = l->metadata();
     127             : 
     128         155 :         DBRequest req;
     129         155 :         req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
     130         155 :         req.key = std::move(req_key);
     131             : 
     132             :         //Add it to defer list
     133         155 :         ltable->LinkDefAdd(&req);
     134             : 
     135         155 :         ltable->DelLink(node, right, edge);
     136         155 :     }
     137         111 : }
     138             : 
     139        1392 : void IFMapAgentTable::DeleteNode(IFMapNode *node) {
     140             : 
     141             : 
     142        1392 :     if ((node->HasAdjacencies(graph()) == true)) {
     143         111 :         HandlePendingLinks(node);
     144             :     }
     145             : 
     146             :     //Now there should not be any more adjacencies
     147        1392 :     assert((node->HasAdjacencies(graph()) == false));
     148             : 
     149             :     DBTablePartition *partition =
     150        1392 :         static_cast<DBTablePartition *>(GetTablePartition(0));
     151        1392 :     graph()->RemoveNode(node);
     152        1392 :     partition->Delete(node);
     153        1392 : }
     154             : 
     155        1920 : void IFMapAgentTable::NotifyNode(IFMapNode *node) {
     156             :     DBTablePartition *partition =
     157        1920 :         static_cast<DBTablePartition *>(GetTablePartition(0));
     158        1920 :     partition->Change(node);
     159        1920 : }
     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         717 : void IFMapAgentLinkTable::LinkDefAdd(DBRequest *request) {
     166         717 :     RequestKey *key = static_cast<RequestKey *>(request->key.get());
     167             : 
     168         717 :     std::list<DeferredNode>::iterator it;
     169             : 
     170         717 :     std::list<DeferredNode> *left = NULL;
     171         717 :     LinkDefMap::iterator left_it = link_def_map_.find(key->left_key);
     172         717 :     if (link_def_map_.end() != left_it)
     173         212 :         left = left_it->second;
     174             : 
     175         717 :     std::list<DeferredNode> *right = NULL;
     176         717 :     LinkDefMap::iterator right_it = link_def_map_.find(key->right_key);
     177         717 :     if (link_def_map_.end() != right_it)
     178         130 :         right = right_it->second;
     179             : 
     180         717 :     if (request->oper == DBRequest::DB_ENTRY_DELETE)  {
     181             :         //We need to delete the old sequence links as well
     182             :         // remove left->right entry
     183         503 :         if (left) {
     184         277 :             for(it = left->begin(); it != left->end(); it++) {
     185         347 :                 if (((*it).node_key.id_type == key->right_key.id_type) &&
     186         116 :                     ((*it).node_key.id_name == key->right_key.id_name)) {
     187         116 :                     left->erase(it);
     188         116 :                     break;
     189             :                 }
     190             :             }
     191         162 :             RemoveDefListEntry(&link_def_map_, left_it, NULL);
     192             :         }
     193             : 
     194             :         // remove right->left entry
     195         503 :         if (right) {
     196         125 :             for(it = right->begin(); it != right->end(); it++) {
     197         237 :                 if (((*it).node_key.id_type == key->left_key.id_type) &&
     198         116 :                     ((*it).node_key.id_name == key->left_key.id_name)) {
     199         116 :                     right->erase(it);
     200         116 :                     break;
     201             :                 }
     202             :             }
     203         120 :             RemoveDefListEntry(&link_def_map_, right_it, NULL);
     204             :         }
     205             : 
     206         503 :         return;
     207             :     }
     208             : 
     209         214 :     bool push_left = true;
     210             : 
     211             :     // Add/Update left->right entry
     212         214 :     if (left) {
     213             :         // If list already contains, just update the seq number
     214         137 :         for(it = left->begin(); it != left->end(); it++) {
     215          92 :             if (((*it).node_key.id_type == key->right_key.id_type) &&
     216           5 :                     ((*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         164 :         left = new std::list<DeferredNode>();
     225         164 :         link_def_map_[key->left_key] = left;
     226             :     }
     227             : 
     228         214 :     bool push_right = true;
     229             :     // Add/Update right->left entry
     230         214 :     if (right) {
     231             :         // If list already contains, just update the seq number
     232          21 :         for(it = right->begin(); it != right->end(); it++) {
     233          12 :             if (((*it).node_key.id_type == key->left_key.id_type) &&
     234           1 :                     ((*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         204 :         right = new std::list<DeferredNode>();
     243         204 :         link_def_map_[key->right_key] = right;
     244             :     }
     245             : 
     246             :     // Add it to the end of the list
     247         214 :     struct DeferredNode dn;
     248         214 :     dn.link_metadata = key->metadata;
     249         214 :     if (push_left) {
     250         214 :         dn.node_key = key->right_key;
     251         214 :         left->push_back(dn);
     252             :     }
     253         214 :     if (push_right) {
     254         214 :         dn.node_key = key->left_key;
     255         214 :         right->push_back(dn);
     256             :     }
     257         214 :     return;
     258         214 : }
     259             : 
     260        3278 : void IFMapAgentTable::Input(DBTablePartition *partition, DBClient *client,
     261             :                              DBRequest *request) {
     262        3278 :     RequestKey *key = static_cast<RequestKey *>(request->key.get());
     263        3278 :     IFMapAgentTable *table = NULL;
     264             :     struct IFMapAgentData *req_data;
     265             :     IFMapObject *obj;
     266             : 
     267        3278 :     table = TableFind(key->id_type);
     268        3278 :     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        3278 :     IFMapNode *node = EntryLookup(key);
     275        3278 :     if (table->pre_filter_) {
     276        1626 :         DBRequest::DBOperation old_oper = request->oper;
     277        1626 :         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        1626 :         if ((old_oper != DBRequest::DB_ENTRY_DELETE) &&
     284         857 :                 (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        3278 :     if (request->oper == DBRequest::DB_ENTRY_DELETE) {
     291        1350 :         if (node == NULL) {
     292         266 :             IFMAP_AGENT_TRACE(Trace, key->id_seq_num,
     293             :                     "Node " + key->id_name + " not found in Delete");
     294         266 :             return;
     295             :         }
     296             : 
     297        1084 :         if (node->IsDeleted()) {
     298           2 :             IFMAP_AGENT_TRACE(Trace, key->id_seq_num,
     299             :                         "Node " + key->id_name + " already deleted");
     300           2 :             return;
     301             :         }
     302             : 
     303        1082 :         obj = node->GetObject();
     304             :         //We dont accept lesser sequence number updates
     305        1082 :         assert(obj->sequence_number() <= key->id_seq_num);
     306             : 
     307             :         //Upate the sequence number even for deletion of node
     308        1082 :         obj->set_sequence_number(key->id_seq_num);
     309        1082 :         DeleteNode(node);
     310        1082 :         return;
     311             :     }
     312             : 
     313        1928 :     if (request->oper == DBRequest::DB_ENTRY_NOTIFY) {
     314           8 :         if (node) {
     315           8 :             partition->Notify(node);
     316             :         }
     317           8 :         return;
     318             :     }
     319             : 
     320        1920 :     node = EntryLocate(node, key);
     321        1920 :     assert(node);
     322             : 
     323             :     //Get the data from request key and notify oper tables
     324        1920 :     req_data = static_cast<struct IFMapAgentData *>(request->data.get());
     325        1920 :     obj = static_cast<IFMapObject *>(req_data->content.release());
     326             : 
     327             :     //Set the sequence number of the object
     328        1920 :     obj->set_sequence_number(key->id_seq_num);
     329             : 
     330        1920 :     node->Insert(obj);
     331        1920 :     NotifyNode(node);
     332             : 
     333             :     IFMapAgentLinkTable *link_table = static_cast<IFMapAgentLinkTable *>(
     334        1920 :         database()->FindTable(IFMAP_AGENT_LINK_DB_NAME));
     335        1920 :     link_table->EvalDefLink(key);
     336             : }
     337             : 
     338         596 : void IFMapAgentTable::Clear() {
     339         596 :     assert(!HasListeners());
     340             :     DBTablePartition *partition = static_cast<DBTablePartition *>(
     341         596 :         GetTablePartition(0));
     342         596 :     IFMapNode *next = NULL;
     343         596 :     for (IFMapNode *node = static_cast<IFMapNode *>(partition->GetFirst());
     344         596 :          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         596 : }
     353             : 
     354             : 
     355             : // Agent link table routines
     356        3334 : IFMapLink *IFMapAgentLinkTable::FindLink(IFMapNode *left, IFMapNode *right,
     357             :                                   const std::string &metadata) {
     358             : 
     359             :     IFMapLinkTable *table = static_cast<IFMapLinkTable *>(
     360        3334 :         database()->FindTable(IFMAP_AGENT_LINK_DB_NAME));
     361        3334 :     assert(table != NULL);
     362        3334 :     IFMapLink *link = table->FindLink(metadata, left, right);
     363        3334 :     return (link ? (link->IsDeleted() ? NULL : link) : NULL);
     364             : }
     365             : 
     366        1594 : void IFMapAgentLinkTable::AddLink(IFMapNode *left, IFMapNode *right,
     367             :                                   const std::string &metadata,
     368             :                                   uint64_t seq) {
     369             : 
     370             :     IFMapLinkTable *table = static_cast<IFMapLinkTable *>(
     371        1594 :         database()->FindTable(IFMAP_AGENT_LINK_DB_NAME));
     372        1594 :     assert(table != NULL);
     373             : 
     374        1594 :     IFMapLink *link = table->AddLink(left, right, metadata, seq,
     375        1594 :                                      IFMapOrigin(IFMapOrigin::UNKNOWN));
     376        1594 :     graph()->Link(left, right, (DBGraphEdge *)link);
     377        1594 : }
     378             : 
     379        1560 : void IFMapAgentLinkTable::DelLink(IFMapNode *left, IFMapNode *right, DBGraphEdge *edge) {
     380             :     IFMapAgentLinkTable *table = static_cast<IFMapAgentLinkTable *>(
     381        1560 :         database()->FindTable(IFMAP_AGENT_LINK_DB_NAME));
     382        1560 :     assert(table != NULL);
     383        1560 :     table->DeleteLink(static_cast<IFMapLink *>(edge));
     384        1560 : }
     385             : 
     386           4 : IFMapAgentLinkTable::IFMapAgentLinkTable(DB *db, const string &name, DBGraph *graph)
     387           4 :         : IFMapLinkTable(db, name, graph) {
     388           4 : }
     389             : 
     390           4 : DBTable *IFMapAgentLinkTable::CreateTable(DB *db, const string &name,
     391             :                                      DBGraph *graph) {
     392           4 :     IFMapAgentLinkTable *table = new IFMapAgentLinkTable(db, name, graph);
     393           4 :     table->Init();
     394           4 :     return table;
     395             : }
     396             : 
     397             : 
     398           4 : void IFMapAgentLinkTable_Init(DB *db, DBGraph *graph) {
     399           4 :     db->RegisterFactory(IFMAP_AGENT_LINK_DB_NAME,
     400             :         boost::bind(&IFMapAgentLinkTable::CreateTable, _1, _2, graph));
     401           4 :     db->CreateTable(IFMAP_AGENT_LINK_DB_NAME);
     402           4 : }
     403             : 
     404        3896 : void IFMapAgentLinkTable::Input(DBTablePartition *partition, DBClient *client,
     405             :                            DBRequest *req) {
     406             : 
     407        3896 :     RequestKey *key = static_cast<RequestKey *>(req->key.get());
     408             : 
     409             :     IFMapNode *left;
     410        3896 :     left = IFMapAgentTable::TableEntryLookup(database(), &key->left_key);
     411        3896 :     if (!left) {
     412         437 :         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         437 :         LinkDefAdd(req);
     417         437 :         return;
     418             :     }
     419             : 
     420             :     IFMapNode *right;
     421        3459 :     right = IFMapAgentTable::TableEntryLookup(database(), &key->right_key);
     422        3459 :     if (!right) {
     423          52 :         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          52 :         LinkDefAdd(req);
     428          52 :         return;
     429             :     }
     430             : 
     431        3407 :     if (left->IsDeleted()) {
     432          65 :         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          65 :         LinkDefAdd(req);
     438          65 :         return;
     439             :     }
     440             : 
     441        3342 :     if (right->IsDeleted()) {
     442           8 :         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           8 :         LinkDefAdd(req);
     448           8 :         return;
     449             :     }
     450             : 
     451        3334 :     IFMapObject *obj = left->GetObject();
     452        3334 :     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        3334 :     obj = right->GetObject();
     461        3334 :     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        3334 :     DBGraphEdge *link = FindLink(left, right, key->metadata);
     470             : 
     471        3334 :     if (req->oper == DBRequest::DB_ENTRY_ADD_CHANGE) {
     472        1925 :         if (link == NULL) {
     473        1594 :             AddLink(left, right, key->metadata, key->left_key.id_seq_num);
     474             :         } else {
     475         331 :             IFMapOrigin origin(IFMapOrigin::UNKNOWN);
     476         331 :             IFMapLink *l = static_cast<IFMapLink *>(link);
     477         331 :             l->UpdateProperties(origin, key->left_key.id_seq_num);
     478             :         }
     479             :     } else {
     480        1409 :         if (link == NULL) {
     481           4 :             return;
     482             :         }
     483        1405 :         DelLink(left, right, link);
     484             :     }
     485             : }
     486             : 
     487         470 : bool IFMapAgentLinkTable::RemoveDefListEntry
     488             :     (LinkDefMap *map, LinkDefMap::iterator &map_it,
     489             :      std::list<DeferredNode>::iterator *list_it) {
     490             : 
     491         470 :     std::list<DeferredNode> *list = map_it->second;
     492         470 :     if (list_it) {
     493         137 :         list->erase(*list_it);
     494             :     }
     495             : 
     496         470 :     if (list->size()) {
     497         102 :         return false;
     498             :     }
     499         368 :     map->erase(map_it);
     500         368 :     delete list;
     501         368 :     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        1920 : void IFMapAgentLinkTable::EvalDefLink(IFMapTable::RequestKey *key) {
     511        1920 :     LinkDefMap::iterator link_defmap_it = link_def_map_.find(*key);
     512        1920 :     if (link_def_map_.end() == link_defmap_it)
     513        1869 :         return;
     514             : 
     515          51 :     std::list<DeferredNode> *left_list = link_defmap_it->second;
     516          51 :     std::list<DeferredNode>::iterator left_it, left_list_entry;
     517         110 :     for(left_it = left_list->begin(); left_it != left_list->end();) {
     518          59 :         left_list_entry = left_it++;
     519             : 
     520             :         // If link seq is older, dont consider the link.
     521          59 :         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          59 :         IFMapNode *node = IFMapAgentTable::TableEntryLookup(database(),
     526          59 :                     &((*left_list_entry).node_key));
     527          59 :         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          59 :         IFMapObject *obj = node->GetObject();
     533          59 :         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          59 :             link_def_map_.find((*left_list_entry).node_key);
     540          59 :         assert(link_def_map_.end() != right_defmap_it);
     541             : 
     542          59 :         std::list<DeferredNode> *right_list = right_defmap_it->second;
     543          59 :         std::list<DeferredNode>::iterator right_it, right_list_entry;
     544          59 :         bool removed_something = false;
     545         118 :         for(right_it = right_list->begin(); right_it !=
     546         118 :                 right_list->end(); right_it++) {
     547             : 
     548             :             // If link seq is older, dont consider the link.
     549          59 :             if ((*right_it).node_key.id_seq_num < key->id_seq_num)
     550           0 :                 continue;
     551             : 
     552         118 :             if ((*right_it).node_key.id_type == key->id_type &&
     553          59 :                     (*right_it).node_key.id_name == key->id_name) {
     554          59 :                 RemoveDefListEntry(&link_def_map_, right_defmap_it, &right_it);
     555          59 :                 removed_something = true;
     556          59 :                 break;
     557             :             }
     558             :         }
     559             : 
     560             :         //We should have removed something in the above iteration
     561          59 :         assert(removed_something);
     562             : 
     563             :         //Remove from deferred list before enqueing
     564          59 :         unique_ptr <RequestKey> req_key (new RequestKey);
     565          59 :         req_key->left_key = *key;
     566          59 :         req_key->right_key = (*left_list_entry).node_key;
     567          59 :         req_key->metadata = (*left_list_entry).link_metadata;
     568             :         // Dont delete left_list_entry. Its passed in req structure
     569          59 :         left_list->erase(left_list_entry);
     570             : 
     571          59 :         DBRequest req;
     572          59 :         req.key = std::move(req_key);
     573          59 :         req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
     574          59 :         Enqueue(&req);
     575          59 :     }
     576             : 
     577             :     // If list does not have any entries, delete the list
     578          51 :     RemoveDefListEntry(&link_def_map_, link_defmap_it, NULL);
     579             : }
     580             : 
     581         276 : void IFMapAgentLinkTable::DestroyDefLink(uint64_t seq) {
     582             :     std::list<DeferredNode> *ent;
     583         276 :     std::list<DeferredNode>::iterator it, list_entry;
     584         276 :     IFMapAgentLinkTable::LinkDefMap::iterator dlist_it, temp;
     585             : 
     586         350 :     for(dlist_it = link_def_map_.begin(); dlist_it != link_def_map_.end(); ) {
     587          74 :         temp = dlist_it++;
     588          74 :         ent = temp->second;
     589          78 :         for(it = ent->begin(); it != ent->end();) {
     590          78 :             list_entry = it++;
     591             : 
     592             :             //Delete the deferred link if it is old seq
     593          78 :             if ((*list_entry).node_key.id_seq_num < seq) {
     594          78 :                 if (RemoveDefListEntry(&link_def_map_, temp,
     595          78 :                             &list_entry) == true) {
     596             :                     //The list has been deleted. Move to the next map
     597             :                     //entry
     598          74 :                     break;
     599             :                 }
     600             :             }
     601             :         }
     602             :     }
     603         276 : }
     604             : 
     605             : //Stale Cleaner functionality
     606             : class IFMapAgentStaleCleaner::IFMapAgentStaleCleanerWorker : public Task {
     607             : public:
     608             : 
     609         276 :     IFMapAgentStaleCleanerWorker(DB *db, DBGraph *graph, uint64_t seq):
     610             :         Task(TaskScheduler::GetInstance()->GetTaskId("db::DBTable"), 0),
     611         276 :         db_(db), graph_(graph), seq_(seq) {
     612         276 :     }
     613             : 
     614         276 :     bool Run() {
     615         276 :         IFMAP_AGENT_TRACE(Trace, seq_,
     616             :                 "IFMap Config Audit start:");
     617             :         //Handle the links first
     618         276 :         DBGraph::edge_iterator e_next(graph_);
     619         276 :         for (DBGraph::edge_iterator e_iter = graph_->edge_list_begin();
     620         310 :             e_iter != graph_->edge_list_end(); e_iter = e_next) {
     621             : 
     622          34 :             const DBGraph::DBEdgeInfo &tuple = *e_iter;
     623             : 
     624          34 :             e_next = ++e_iter;
     625             : 
     626          34 :             IFMapNode *lhs = static_cast<IFMapNode *>(boost::get<0>(tuple));
     627          34 :             IFMapNode *rhs = static_cast<IFMapNode *>(boost::get<1>(tuple));
     628          34 :             IFMapLink *link = static_cast<IFMapLink *>(boost::get<2>(tuple));
     629          34 :             assert(link);
     630             : 
     631          34 :             bool exists = false;
     632             :             IFMapLink::LinkOriginInfo origin_info =
     633          34 :                 link->GetOriginInfo(IFMapOrigin::UNKNOWN, &exists);
     634          34 :             if (exists && (origin_info.sequence_number < seq_ )) {
     635             :                 IFMapAgentLinkTable *ltable = static_cast<IFMapAgentLinkTable *>(
     636          34 :                     db_->FindTable(IFMAP_AGENT_LINK_DB_NAME));
     637          34 :                 IFMAP_AGENT_TRACE(Trace,
     638             :                      origin_info.sequence_number, "Deleting Link between " +
     639             :                      lhs->name() + rhs->name());
     640          34 :                 ltable->DeleteLink(link);
     641             :             }
     642             :         }
     643             : 
     644             :         //Handle the vertices now
     645         276 :         DBGraph::vertex_iterator v_next(graph_);
     646         276 :         for (DBGraph::vertex_iterator v_iter = graph_->vertex_list_begin();
     647         586 :             v_iter != graph_->vertex_list_end(); v_iter = v_next) {
     648             : 
     649         310 :             IFMapNode *node = static_cast<IFMapNode *>(v_iter.operator->());
     650         310 :             v_next = ++v_iter;
     651             : 
     652         310 :             IFMapObject *obj = node->GetObject();
     653         310 :             assert(obj);
     654         310 :             if (obj->sequence_number() < seq_) {
     655         310 :                 IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table());
     656         310 :                 IFMAP_AGENT_TRACE(Trace, obj->sequence_number(),
     657             :                         "Deleting node " + node->name());
     658         310 :                 table->DeleteNode(node);
     659             :             }
     660             :         }
     661             : 
     662             :         //Handle deferred list
     663             :         IFMapAgentLinkTable *table = static_cast<IFMapAgentLinkTable *>(
     664         276 :                     db_->FindTable(IFMAP_AGENT_LINK_DB_NAME));
     665         276 :         table->DestroyDefLink(seq_);
     666             : 
     667         276 :         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           4 : IFMapAgentStaleCleaner::~IFMapAgentStaleCleaner() {
     680           4 : }
     681             : 
     682           4 : IFMapAgentStaleCleaner::IFMapAgentStaleCleaner(DB *db, DBGraph *graph) :
     683           4 :         db_(db), graph_(graph) {
     684           4 : }
     685             : 
     686         276 : bool IFMapAgentStaleCleaner::StaleTimeout(uint64_t seq) {
     687         276 :     seq_ = seq;
     688         276 :     IFMapAgentStaleCleanerWorker *cleaner = new IFMapAgentStaleCleanerWorker(db_, graph_, seq_);
     689         276 :     TaskScheduler *sch = TaskScheduler::GetInstance();
     690         276 :     sch->Enqueue(cleaner);
     691         276 :     return false;
     692             : }
     693             : 
     694           4 : void IFMapAgentStaleCleaner::Clear() {
     695             :     IFMapLinkTable *table = static_cast<IFMapLinkTable *>(
     696           4 :         db_->FindTable(IFMAP_AGENT_LINK_DB_NAME));
     697           4 :     table->Clear();
     698           4 :     IFMapTable::ClearTables(db_);
     699           4 : }

Generated by: LCOV version 1.14