Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #include "ifmap/ifmap_link_table.h" 6 : 7 : #include <boost/bind/bind.hpp> 8 : 9 : #include "db/db.h" 10 : #include "db/db_graph.h" 11 : #include "db/db_table_partition.h" 12 : #include "ifmap/ifmap_link.h" 13 : #include "ifmap/ifmap_log.h" 14 : #include "ifmap/ifmap_log_types.h" 15 : 16 : using namespace std; 17 : using namespace boost::placeholders; 18 : 19 8214 : IFMapLinkTable::IFMapLinkTable(DB *db, const string &name, DBGraph *graph) 20 8214 : : DBGraphTable(db, name, graph) { 21 8214 : } 22 : 23 0 : void IFMapLinkTable::Input(DBTablePartition *partition, DBClient *client, 24 : DBRequest *req) { 25 0 : assert(false); 26 : } 27 : 28 363200 : std::unique_ptr<DBEntry> IFMapLinkTable::AllocEntry( 29 : const DBRequestKey *key) const { 30 363200 : const RequestKey *rkey = static_cast<const RequestKey *>(key); 31 363200 : unique_ptr<DBEntry> entry(new IFMapLink(rkey->name)); 32 363200 : return entry; 33 : } 34 : 35 : // Generate an unique name for the link node and it should 36 : // be independent of the order in which the right and left nodes are specified 37 363172 : std::string IFMapLinkTable::LinkKey(const string &metadata, 38 : IFMapNode *left, IFMapNode *right) { 39 363172 : ostringstream oss; 40 363172 : if (left->ToString() < right->ToString()) { 41 154968 : oss << metadata << "," << left->ToString() << "," << right->ToString(); 42 : } else { 43 208204 : oss << metadata << "," << right->ToString() << "," << left->ToString(); 44 : } 45 726344 : return oss.str(); 46 363172 : } 47 : 48 159908 : IFMapLink *IFMapLinkTable::AddLink(IFMapNode *left, IFMapNode *right, 49 : const string &metadata, uint64_t sequence_number, 50 : const IFMapOrigin &origin) { 51 : DBTablePartition *partition = 52 159908 : static_cast<DBTablePartition *>(GetTablePartition(0)); 53 : 54 159908 : string link_name = LinkKey(metadata, left, right); 55 159908 : IFMapLink *link = FindLink(link_name); 56 159908 : if (link) { 57 4 : assert(link->IsDeleted()); 58 4 : link->SetLinkRevival(true); 59 4 : link->ClearDelete(); 60 4 : link->set_last_change_at_to_now(); 61 4 : partition->Change(link); 62 : } else { 63 159904 : link = new IFMapLink(link_name); 64 159904 : partition->Add(link); 65 : } 66 159908 : link->SetProperties(left, right, metadata, sequence_number, origin); 67 159908 : assert(dynamic_cast<IFMapNode *>(left)); 68 159908 : assert(dynamic_cast<IFMapNode *>(right)); 69 159908 : return link; 70 159908 : } 71 : 72 203232 : IFMapLink *IFMapLinkTable::FindLink(const string &metadata, IFMapNode *left, IFMapNode *right) { 73 203232 : string link_name = LinkKey(metadata, left, right); 74 406464 : return FindLink(link_name); 75 203232 : } 76 : 77 363200 : IFMapLink *IFMapLinkTable::FindLink(const string &name) { 78 : 79 : DBTablePartition *partition = 80 363200 : static_cast<DBTablePartition *>(GetTablePartition(0)); 81 363200 : RequestKey key; 82 363200 : key.name = name; 83 726400 : return static_cast<IFMapLink *>(partition->Find(&key)); 84 363200 : } 85 : 86 0 : IFMapLink *IFMapLinkTable::FindNextLink(const string &name) { 87 : 88 : DBTablePartition *partition = 89 0 : static_cast<DBTablePartition *>(GetTablePartition(0)); 90 0 : RequestKey key; 91 0 : key.name = name; 92 0 : return static_cast<IFMapLink *>(partition->FindNext(&key)); 93 0 : } 94 : 95 33371 : void IFMapLinkTable::DeleteLink(IFMapLink *link) { 96 33371 : DBGraphEdge *edge = static_cast<DBGraphEdge *>(link); 97 33371 : graph()->Unlink(edge); 98 33371 : link->set_last_change_at_to_now(); 99 33371 : link->ClearNodes(); 100 : DBTablePartition *partition = 101 33371 : static_cast<DBTablePartition *>(GetTablePartition(0)); 102 33371 : partition->Delete(edge); 103 33371 : } 104 : 105 33285 : void IFMapLinkTable::DeleteLink(IFMapLink *link, const IFMapOrigin &origin) { 106 33285 : link->RemoveOriginInfo(origin.origin); 107 33285 : if (link->is_origin_empty()) { 108 33279 : DeleteLink(link); 109 : } 110 33285 : } 111 : 112 8213 : DBTable *IFMapLinkTable::CreateTable(DB *db, const string &name, 113 : DBGraph *graph) { 114 8213 : IFMapLinkTable *table = new IFMapLinkTable(db, name, graph); 115 8213 : table->Init(); 116 8213 : return table; 117 : } 118 : 119 8214 : void IFMapLinkTable::Clear() { 120 : DBTablePartition *partition = static_cast<DBTablePartition *>( 121 8214 : GetTablePartition(0)); 122 : 123 8214 : assert(!HasListeners()); 124 8214 : for (IFMapLink *link = static_cast<IFMapLink *>(partition->GetFirst()), 125 134751 : *next = NULL; link != NULL; link = next) { 126 126537 : next = static_cast<IFMapLink *>(partition->GetNext(link)); 127 126537 : if (link->IsDeleted()) { 128 0 : continue; 129 : } 130 126537 : graph()->Unlink(link); 131 126537 : partition->Delete(link); 132 : } 133 8214 : } 134 : 135 8213 : void IFMapLinkTable_Init(DB *db, DBGraph *graph) { 136 : DBTable *table = 137 8213 : IFMapLinkTable::CreateTable(db, "__ifmap_metadata__.0", graph); 138 8213 : db->AddTable(table); 139 8213 : } 140 : 141 159 : void IFMapLinkTable_Clear(DB *db) { 142 : IFMapLinkTable *ltable = static_cast<IFMapLinkTable *>( 143 159 : db->FindTable("__ifmap_metadata__.0")); 144 159 : ltable->Clear(); 145 159 : }