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