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

Generated by: LCOV version 1.14