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 287 : void AgentDBEntry::SetRefState() const {
10 287 : 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 287 : AgentDBEntry *entry = (AgentDBEntry *)this;
14 287 : entry->SetState(table, table->GetRefListenerId(), new AgentDBState(this));
15 287 : }
16 :
17 287 : void AgentDBEntry::ClearRefState() const {
18 287 : 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 287 : AgentDBEntry *entry = (AgentDBEntry *)this;
22 287 : table->OnZeroRefcount(entry);
23 287 : delete(entry->GetState(table, table->GetRefListenerId()));
24 287 : entry->ClearState(table, table->GetRefListenerId());
25 287 : }
26 :
27 1992 : bool AgentDBEntry::IsActive() const {
28 1992 : return !IsDeleted();
29 : }
30 :
31 94 : DBState *AgentDBEntry::GetAgentDBEntryState(int listener_id) {
32 : DBState *state = dynamic_cast<DBState *>
33 94 : (GetState(get_table(), listener_id));
34 94 : return state;
35 : }
36 :
37 77 : const DBState *AgentDBEntry::GetAgentDBEntryState(int listener_id) const {
38 : const DBState *state = dynamic_cast<const DBState *>
39 77 : (GetState(get_table(), listener_id));
40 77 : return state;
41 : }
42 :
43 284 : void AgentDBEntry::AllocateResources(ResourceManager *resource_manager) {
44 284 : }
45 :
46 284 : void AgentDBEntry::FreeResources(ResourceManager *resource_manager) {
47 284 : }
48 :
49 116 : void AgentDBEntry::PostAdd() {
50 116 : }
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 211 : AgentDBEntry *AgentDBTable::FindActiveEntry(const DBEntry *key) {
111 211 : AgentDBEntry *entry = static_cast<AgentDBEntry *> (Find(key));
112 211 : if (entry && (entry->IsActive() == false)) {
113 0 : return NULL;
114 : }
115 211 : return entry;
116 : }
117 :
118 9 : AgentDBEntry *AgentDBTable::FindActiveEntryNoLock(const DBRequestKey *key) {
119 9 : AgentDBEntry *entry = static_cast<AgentDBEntry *>(FindNoLock(key));
120 9 : if (entry && (entry->IsActive() == false)) {
121 0 : return NULL;
122 : }
123 9 : return entry;
124 : }
125 :
126 1961 : AgentDBEntry *AgentDBTable::FindActiveEntry(const DBRequestKey *key) {
127 1961 : AgentDBEntry *entry = static_cast<AgentDBEntry *>(Find(key));
128 1961 : if (entry && (entry->IsActive() == false)) {
129 0 : return NULL;
130 : }
131 1961 : 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 1340 : AgentDBEntry *AgentDBTable::Find(const DBRequestKey *key, bool ret_del) {
143 1340 : if (ret_del) {
144 1278 : return Find(key);
145 : } else {
146 62 : return FindActiveEntry(key);
147 : }
148 : }
149 :
150 211 : AgentDBEntry *AgentDBTable::Find(const DBEntry *key) {
151 211 : return static_cast<AgentDBEntry *> (DBTable::Find(key));
152 : }
153 :
154 3239 : AgentDBEntry *AgentDBTable::Find(const DBRequestKey *key) {
155 3239 : return static_cast<AgentDBEntry *>(DBTable::Find(key));
156 : }
157 :
158 284 : void AgentDBTablePartition::Add(DBEntry *entry) {
159 284 : entry->set_table_partition(static_cast<DBTablePartBase *>(this));
160 284 : Agent *agent = (static_cast<AgentDBTable *>(parent()))->agent();
161 284 : if (agent) {
162 : (static_cast<AgentDBEntry *>(entry))->AllocateResources
163 284 : (agent->resource_manager());
164 : }
165 284 : DBTablePartition::Add(entry);
166 284 : static_cast<AgentDBEntry *>(entry)->PostAdd();
167 284 : }
168 :
169 284 : void AgentDBTablePartition::Remove(DBEntryBase *entry) {
170 284 : AgentDBEntry *agent_dbentry = static_cast<AgentDBEntry *>(entry);
171 284 : if (agent_dbentry->GetRefCount() != 0) {
172 0 : agent_dbentry->ClearOnRemoveQ();
173 0 : return;
174 : }
175 284 : Agent *agent = (static_cast<AgentDBTable *>(parent()))->agent();
176 284 : if (agent) {
177 : (static_cast<AgentDBEntry *>(entry))->FreeResources
178 284 : (agent->resource_manager());
179 : }
180 284 : DBTablePartition::Remove(entry);
181 : }
182 :
183 82 : bool AgentDBTable::IFNodeToUuid(IFMapNode *node, boost::uuids::uuid &id) {
184 82 : id = boost::uuids::nil_uuid();
185 82 : return false;
186 : }
187 :
188 1233 : void AgentDBTable::Input(DBTablePartition *partition, DBClient *client,
189 : DBRequest *req) {
190 1233 : AgentKey *key = static_cast<AgentKey *>(req->key.get());
191 :
192 1233 : if (key->sub_op_ == AgentKey::ADD_DEL_CHANGE) {
193 1148 : DBTable::Input(partition, client, req);
194 1148 : return;
195 : }
196 :
197 85 : AgentDBEntry *entry = static_cast<AgentDBEntry *>(partition->Find(key));
198 85 : if (entry && (entry->IsActive() == false)) {
199 4 : return;
200 : }
201 :
202 : // Dont create an entry on RESYNC sub_op
203 81 : if (key->sub_op_ == AgentKey::RESYNC) {
204 81 : if (entry == NULL) {
205 40 : return;
206 : }
207 41 : if (Resync(entry, req)) {
208 38 : partition->Change(entry);
209 : }
210 41 : 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 : }
|