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