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