Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #include "agent_cmn.h"
6 : #include "agent_db.h"
7 : #include <cfg/cfg_init.h>
8 :
9 263 : void AgentDBEntry::SetRefState() const {
10 263 : AgentDBTable *table = static_cast<AgentDBTable *>(get_table());
11 : // Force calling SetState on a const object.
12 : // Ideally, SetState should be 'const method' and StateMap mutable
13 263 : AgentDBEntry *entry = (AgentDBEntry *)this;
14 263 : entry->SetState(table, table->GetRefListenerId(), new AgentDBState(this));
15 263 : }
16 :
17 263 : void AgentDBEntry::ClearRefState() const {
18 263 : AgentDBTable *table = static_cast<AgentDBTable *>(get_table());
19 : // Force calling SetState on a const object.
20 : // Ideally, ClearState should be 'const method' and StateMap mutable
21 263 : AgentDBEntry *entry = (AgentDBEntry *)this;
22 263 : table->OnZeroRefcount(entry);
23 263 : delete(entry->GetState(table, table->GetRefListenerId()));
24 263 : entry->ClearState(table, table->GetRefListenerId());
25 263 : }
26 :
27 1873 : bool AgentDBEntry::IsActive() const {
28 1873 : return !IsDeleted();
29 : }
30 :
31 86 : DBState *AgentDBEntry::GetAgentDBEntryState(int listener_id) {
32 : DBState *state = dynamic_cast<DBState *>
33 86 : (GetState(get_table(), listener_id));
34 86 : return state;
35 : }
36 :
37 60 : const DBState *AgentDBEntry::GetAgentDBEntryState(int listener_id) const {
38 : const DBState *state = dynamic_cast<const DBState *>
39 60 : (GetState(get_table(), listener_id));
40 60 : return state;
41 : }
42 :
43 261 : void AgentDBEntry::AllocateResources(ResourceManager *resource_manager) {
44 261 : }
45 :
46 261 : void AgentDBEntry::FreeResources(ResourceManager *resource_manager) {
47 261 : }
48 :
49 105 : void AgentDBEntry::PostAdd() {
50 105 : }
51 :
52 10 : static bool FlushNotify(DBTablePartBase *partition, DBEntryBase *e) {
53 10 : if (e->IsDeleted()) {
54 2 : return true;
55 : }
56 :
57 8 : DBRequest req(DBRequest::DB_ENTRY_DELETE);
58 8 : req.key = e->GetDBRequestKey();
59 8 : (static_cast<AgentDBTable *>(e->get_table()))->Process(req);
60 8 : return true;
61 8 : }
62 :
63 8 : static void FlushWalkDone(DBTable::DBTableWalkRef walk_ref,
64 : DBTableBase *partition) {
65 8 : AgentDBTable *table = static_cast<AgentDBTable *>(partition);
66 8 : table->ReleaseWalker(walk_ref);
67 8 : table->reset_flush_walk_ref();
68 8 : }
69 :
70 24 : AgentDBTable::AgentDBTable(DB *db, const std::string &name) :
71 24 : DBTable(db, name), ref_listener_id_(-1), agent_(NULL),
72 24 : OperDBTraceBuf(SandeshTraceBufferCreate(("Oper " + name), 5000)),
73 48 : flush_walk_ref_() {
74 24 : ref_listener_id_ = Register(boost::bind(&AgentDBTable::Notify,
75 : this, _1, _2));
76 24 : };
77 :
78 0 : AgentDBTable::AgentDBTable(DB *db, const std::string &name,
79 0 : bool del_on_zero_refcount) :
80 0 : DBTable(db, name), ref_listener_id_(-1) , agent_(NULL),
81 0 : OperDBTraceBuf(SandeshTraceBufferCreate(("Oper " + name), 5000)),
82 0 : flush_walk_ref_() {
83 0 : ref_listener_id_ = Register(boost::bind(&AgentDBTable::Notify,
84 : this, _1, _2));
85 0 : };
86 :
87 24 : AgentDBTable::~AgentDBTable() {
88 24 : assert(HasWalkers() == false);
89 24 : }
90 :
91 0 : void AgentDBTable::NotifyEntry(DBEntryBase *e) {
92 0 : agent_->ConcurrencyCheck();
93 : DBTablePartBase *tpart =
94 0 : static_cast<DBTablePartition *>(GetTablePartition(e));
95 0 : tpart->Notify(e);
96 0 : }
97 :
98 8 : void AgentDBTable::reset_flush_walk_ref() {
99 8 : flush_walk_ref_ = NULL;
100 8 : }
101 :
102 0 : AgentDBEntry *AgentDBTable::FindActiveEntryNoLock(const DBEntry *key) {
103 0 : AgentDBEntry *entry = static_cast<AgentDBEntry *> (FindNoLock(key));
104 0 : if (entry && (entry->IsActive() == false)) {
105 0 : return NULL;
106 : }
107 0 : return entry;
108 : }
109 :
110 201 : AgentDBEntry *AgentDBTable::FindActiveEntry(const DBEntry *key) {
111 201 : AgentDBEntry *entry = static_cast<AgentDBEntry *> (Find(key));
112 201 : if (entry && (entry->IsActive() == false)) {
113 0 : return NULL;
114 : }
115 201 : return entry;
116 : }
117 :
118 8 : AgentDBEntry *AgentDBTable::FindActiveEntryNoLock(const DBRequestKey *key) {
119 8 : AgentDBEntry *entry = static_cast<AgentDBEntry *>(FindNoLock(key));
120 8 : if (entry && (entry->IsActive() == false)) {
121 0 : return NULL;
122 : }
123 8 : return entry;
124 : }
125 :
126 1814 : AgentDBEntry *AgentDBTable::FindActiveEntry(const DBRequestKey *key) {
127 1814 : AgentDBEntry *entry = static_cast<AgentDBEntry *>(Find(key));
128 1814 : if (entry && (entry->IsActive() == false)) {
129 0 : return NULL;
130 : }
131 1814 : return entry;
132 : }
133 :
134 0 : AgentDBEntry *AgentDBTable::Find(const DBEntry *key, bool ret_del) {
135 0 : if (ret_del) {
136 0 : return Find(key);
137 : } else {
138 0 : return FindActiveEntry(key);
139 : }
140 : }
141 :
142 1250 : AgentDBEntry *AgentDBTable::Find(const DBRequestKey *key, bool ret_del) {
143 1250 : if (ret_del) {
144 1194 : return Find(key);
145 : } else {
146 56 : return FindActiveEntry(key);
147 : }
148 : }
149 :
150 201 : AgentDBEntry *AgentDBTable::Find(const DBEntry *key) {
151 201 : return static_cast<AgentDBEntry *> (DBTable::Find(key));
152 : }
153 :
154 3008 : AgentDBEntry *AgentDBTable::Find(const DBRequestKey *key) {
155 3008 : return static_cast<AgentDBEntry *>(DBTable::Find(key));
156 : }
157 :
158 261 : void AgentDBTablePartition::Add(DBEntry *entry) {
159 261 : entry->set_table_partition(static_cast<DBTablePartBase *>(this));
160 261 : Agent *agent = (static_cast<AgentDBTable *>(parent()))->agent();
161 261 : if (agent) {
162 : (static_cast<AgentDBEntry *>(entry))->AllocateResources
163 261 : (agent->resource_manager());
164 : }
165 261 : DBTablePartition::Add(entry);
166 261 : static_cast<AgentDBEntry *>(entry)->PostAdd();
167 261 : }
168 :
169 261 : void AgentDBTablePartition::Remove(DBEntryBase *entry) {
170 261 : AgentDBEntry *agent_dbentry = static_cast<AgentDBEntry *>(entry);
171 261 : if (agent_dbentry->GetRefCount() != 0) {
172 0 : agent_dbentry->ClearOnRemoveQ();
173 0 : return;
174 : }
175 261 : Agent *agent = (static_cast<AgentDBTable *>(parent()))->agent();
176 261 : if (agent) {
177 : (static_cast<AgentDBEntry *>(entry))->FreeResources
178 261 : (agent->resource_manager());
179 : }
180 261 : DBTablePartition::Remove(entry);
181 : }
182 :
183 66 : bool AgentDBTable::IFNodeToUuid(IFMapNode *node, boost::uuids::uuid &id) {
184 66 : id = boost::uuids::nil_uuid();
185 66 : return false;
186 : }
187 :
188 1130 : void AgentDBTable::Input(DBTablePartition *partition, DBClient *client,
189 : DBRequest *req) {
190 1130 : AgentKey *key = static_cast<AgentKey *>(req->key.get());
191 :
192 1130 : if (key->sub_op_ == AgentKey::ADD_DEL_CHANGE) {
193 1063 : DBTable::Input(partition, client, req);
194 1063 : return;
195 : }
196 :
197 67 : AgentDBEntry *entry = static_cast<AgentDBEntry *>(partition->Find(key));
198 67 : if (entry && (entry->IsActive() == false)) {
199 4 : return;
200 : }
201 :
202 : // Dont create an entry on RESYNC sub_op
203 63 : if (key->sub_op_ == AgentKey::RESYNC) {
204 63 : if (entry == NULL) {
205 24 : return;
206 : }
207 39 : if (Resync(entry, req)) {
208 36 : partition->Change(entry);
209 : }
210 39 : return;
211 : }
212 0 : return;
213 : }
214 :
215 1 : void AgentDBTable::Clear() {
216 1 : Unregister(ref_listener_id_);
217 1 : assert(!HasListeners());
218 : DBTablePartition *partition = static_cast<DBTablePartition *>(
219 1 : GetTablePartition(0));
220 :
221 1 : DBEntryBase *next = NULL;
222 1 : for (DBEntryBase *entry = partition->GetFirst(); entry; entry = next) {
223 0 : next = partition->GetNext(entry);
224 0 : if (entry->IsDeleted()) {
225 0 : continue;
226 : }
227 0 : partition->Delete(entry);
228 : }
229 1 : }
230 :
231 8 : void AgentDBTable::Process(DBRequest &req) {
232 8 : agent_->ConcurrencyCheck();
233 : DBTablePartition *tpart =
234 8 : static_cast<DBTablePartition *>(GetTablePartition(req.key.get()));
235 8 : tpart->Process(NULL, &req);
236 8 : }
237 :
238 8 : void AgentDBTable::Flush() {
239 16 : flush_walk_ref_ = AllocWalker(boost::bind(FlushNotify, _1, _2),
240 8 : boost::bind(FlushWalkDone, _1, _2));
241 8 : WalkAgain(flush_walk_ref_);
242 8 : }
|