OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
agent_db.cc
Go to the documentation of this file.
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 
10  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  AgentDBEntry *entry = (AgentDBEntry *)this;
14  entry->SetState(table, table->GetRefListenerId(), new AgentDBState(this));
15 }
16 
18  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  AgentDBEntry *entry = (AgentDBEntry *)this;
22  table->OnZeroRefcount(entry);
23  delete(entry->GetState(table, table->GetRefListenerId()));
24  entry->ClearState(table, table->GetRefListenerId());
25 }
26 
27 bool AgentDBEntry::IsActive() const {
28  return !IsDeleted();
29 }
30 
32  DBState *state = dynamic_cast<DBState *>
33  (GetState(get_table(), listener_id));
34  return state;
35 }
36 
37 const DBState *AgentDBEntry::GetAgentDBEntryState(int listener_id) const {
38  const DBState *state = dynamic_cast<const DBState *>
39  (GetState(get_table(), listener_id));
40  return state;
41 }
42 
44 }
45 
47 }
48 
50 }
51 
52 static bool FlushNotify(DBTablePartBase *partition, DBEntryBase *e) {
53  if (e->IsDeleted()) {
54  return true;
55  }
56 
58  req.key = e->GetDBRequestKey();
59  (static_cast<AgentDBTable *>(e->get_table()))->Process(req);
60  return true;
61 }
62 
64  DBTableBase *partition) {
65  AgentDBTable *table = static_cast<AgentDBTable *>(partition);
66  table->ReleaseWalker(walk_ref);
67  table->reset_flush_walk_ref();
68 }
69 
70 AgentDBTable::AgentDBTable(DB *db, const std::string &name) :
71  DBTable(db, name), ref_listener_id_(-1), agent_(NULL),
72  OperDBTraceBuf(SandeshTraceBufferCreate(("Oper " + name), 5000)),
73  flush_walk_ref_() {
75  this, _1, _2));
76 };
77 
78 AgentDBTable::AgentDBTable(DB *db, const std::string &name,
79  bool del_on_zero_refcount) :
80  DBTable(db, name), ref_listener_id_(-1) , agent_(NULL),
81  OperDBTraceBuf(SandeshTraceBufferCreate(("Oper " + name), 5000)),
82  flush_walk_ref_() {
84  this, _1, _2));
85 };
86 
88  assert(HasWalkers() == false);
89 }
90 
93  DBTablePartBase *tpart =
94  static_cast<DBTablePartition *>(GetTablePartition(e));
95  tpart->Notify(e);
96 }
97 
99  flush_walk_ref_ = NULL;
100 }
101 
103  AgentDBEntry *entry = static_cast<AgentDBEntry *> (FindNoLock(key));
104  if (entry && (entry->IsActive() == false)) {
105  return NULL;
106  }
107  return entry;
108 }
109 
111  AgentDBEntry *entry = static_cast<AgentDBEntry *> (Find(key));
112  if (entry && (entry->IsActive() == false)) {
113  return NULL;
114  }
115  return entry;
116 }
117 
119  AgentDBEntry *entry = static_cast<AgentDBEntry *>(FindNoLock(key));
120  if (entry && (entry->IsActive() == false)) {
121  return NULL;
122  }
123  return entry;
124 }
125 
127  AgentDBEntry *entry = static_cast<AgentDBEntry *>(Find(key));
128  if (entry && (entry->IsActive() == false)) {
129  return NULL;
130  }
131  return entry;
132 }
133 
134 AgentDBEntry *AgentDBTable::Find(const DBEntry *key, bool ret_del) {
135  if (ret_del) {
136  return Find(key);
137  } else {
138  return FindActiveEntry(key);
139  }
140 }
141 
142 AgentDBEntry *AgentDBTable::Find(const DBRequestKey *key, bool ret_del) {
143  if (ret_del) {
144  return Find(key);
145  } else {
146  return FindActiveEntry(key);
147  }
148 }
149 
151  return static_cast<AgentDBEntry *> (DBTable::Find(key));
152 }
153 
155  return static_cast<AgentDBEntry *>(DBTable::Find(key));
156 }
157 
159  entry->set_table_partition(static_cast<DBTablePartBase *>(this));
160  Agent *agent = (static_cast<AgentDBTable *>(parent()))->agent();
161  if (agent) {
162  (static_cast<AgentDBEntry *>(entry))->AllocateResources
163  (agent->resource_manager());
164  }
165  DBTablePartition::Add(entry);
166  static_cast<AgentDBEntry *>(entry)->PostAdd();
167 }
168 
170  AgentDBEntry *agent_dbentry = static_cast<AgentDBEntry *>(entry);
171  if (agent_dbentry->GetRefCount() != 0) {
172  agent_dbentry->ClearOnRemoveQ();
173  return;
174  }
175  Agent *agent = (static_cast<AgentDBTable *>(parent()))->agent();
176  if (agent) {
177  (static_cast<AgentDBEntry *>(entry))->FreeResources
178  (agent->resource_manager());
179  }
181 }
182 
184  id = boost::uuids::nil_uuid();
185  return false;
186 }
187 
189  DBRequest *req) {
190  AgentKey *key = static_cast<AgentKey *>(req->key.get());
191 
192  if (key->sub_op_ == AgentKey::ADD_DEL_CHANGE) {
193  DBTable::Input(partition, client, req);
194  return;
195  }
196 
197  AgentDBEntry *entry = static_cast<AgentDBEntry *>(partition->Find(key));
198  if (entry && (entry->IsActive() == false)) {
199  return;
200  }
201 
202  // Dont create an entry on RESYNC sub_op
203  if (key->sub_op_ == AgentKey::RESYNC) {
204  if (entry == NULL) {
205  return;
206  }
207  if (Resync(entry, req)) {
208  partition->Change(entry);
209  }
210  return;
211  }
212  return;
213 }
214 
217  assert(!HasListeners());
218  DBTablePartition *partition = static_cast<DBTablePartition *>(
219  GetTablePartition(0));
220 
221  DBEntryBase *next = NULL;
222  for (DBEntryBase *entry = partition->GetFirst(); entry; entry = next) {
223  next = partition->GetNext(entry);
224  if (entry->IsDeleted()) {
225  continue;
226  }
227  partition->Delete(entry);
228  }
229 }
230 
233  DBTablePartition *tpart =
234  static_cast<DBTablePartition *>(GetTablePartition(req.key.get()));
235  tpart->Process(NULL, &req);
236 }
237 
239  flush_walk_ref_ = AllocWalker(boost::bind(FlushNotify, _1, _2),
240  boost::bind(FlushWalkDone, _1, _2));
242 }
bool HasWalkers() const
Definition: db_table.h:128
void ConcurrencyCheck()
Definition: agent.cc:1044
void Notify(DBTablePartBase *partition, DBEntryBase *entry)
Definition: agent_db.h:192
void Process(DBClient *client, DBRequest *req)
DBTableBase::ListenerId GetRefListenerId() const
Definition: agent_db.h:195
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
Definition: db_entry.cc:37
static bool FlushNotify(DBTablePartBase *partition, DBEntryBase *e)
Definition: agent_db.cc:52
DBTableBase * get_table() const
Definition: db_entry.cc:119
DBEntry * Find(const DBEntry *entry)
virtual void Add(DBEntry *entry)
Definition: agent_db.cc:158
bool IsDeleted() const
Definition: db_entry.h:49
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
Definition: db_entry.cc:22
void Flush()
Definition: agent_db.cc:238
virtual DBEntry * GetNext(const DBEntryBase *entry)
uint8_t sub_op_
Definition: agent_db.h:106
DBTableWalkRef AllocWalker(WalkFn walk_fn, WalkCompleteFn walk_complete)
Definition: db_table.cc:613
DBTableBase * parent()
AgentDBEntry * FindActiveEntry(const DBEntry *key)
Definition: agent_db.cc:110
boost::uuids::uuid uuid
void Delete(DBEntryBase *)
AgentDBEntry * FindActiveEntryNoLock(const DBEntry *key)
Definition: agent_db.cc:102
void Unregister(ListenerId listener)
Definition: db_table.cc:186
virtual void Change(DBEntry *entry)
void ReleaseWalker(DBTableWalkRef &walk)
Definition: db_table.cc:619
Agent * agent_
Definition: agent_db.h:223
virtual uint32_t GetRefCount() const =0
DBState * GetAgentDBEntryState(int listener_id)
Definition: agent_db.cc:31
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
Definition: db_table.cc:181
Definition: db.h:24
void ClearOnRemoveQ()
Definition: db_entry.h:59
virtual void AllocateResources(ResourceManager *resource_manager)
Definition: agent_db.cc:43
void WalkAgain(DBTableWalkRef walk)
Definition: db_table.cc:631
virtual void FreeResources(ResourceManager *resource_manager)
Definition: agent_db.cc:46
Definition: agent.h:358
DBTableBase::ListenerId ref_listener_id_
Definition: agent_db.h:222
AgentDBTable(DB *db, const std::string &name)
Definition: agent_db.cc:70
std::unique_ptr< DBRequestKey > key
Definition: db_table.h:48
void set_table_partition(DBTablePartBase *tpart)
Definition: db_entry.cc:111
void ClearRefState() const
Definition: agent_db.cc:17
virtual void Clear()
Definition: agent_db.cc:215
virtual void PostAdd()
Definition: agent_db.cc:49
DBEntry * FindNoLock(const DBEntry *entry)
Definition: db_table.cc:462
AgentDBEntry * Find(const DBEntry *key, bool ret_del)
Definition: agent_db.cc:134
virtual void Process(DBRequest &req)
Definition: agent_db.cc:231
virtual ~AgentDBTable()
Definition: agent_db.cc:87
void ClearState(DBTableBase *tbl_base, ListenerId listener)
Definition: db_entry.cc:73
virtual bool IFNodeToUuid(IFMapNode *node, boost::uuids::uuid &id)
Definition: agent_db.cc:183
virtual KeyPtr GetDBRequestKey() const =0
virtual DBTablePartBase * GetTablePartition(const DBRequestKey *key)
Definition: db_table.cc:436
void reset_flush_walk_ref()
Definition: agent_db.cc:98
void SetRefState() const
Definition: agent_db.cc:9
bool HasListeners() const
Definition: db_table.cc:234
DBEntry * Find(const DBEntry *entry)
Definition: db_table.cc:469
virtual bool Resync(DBEntry *entry, const DBRequest *req)
Definition: agent_db.h:159
virtual void Remove(DBEntryBase *entry)
Definition: agent_db.cc:169
bool IsActive() const
Definition: agent_db.cc:27
virtual void NotifyEntry(DBEntryBase *entry)
Definition: agent_db.cc:91
static void FlushWalkDone(DBTable::DBTableWalkRef walk_ref, DBTableBase *partition)
Definition: agent_db.cc:63
virtual DBEntry * GetFirst()
virtual void Add(DBEntry *entry)
virtual void OnZeroRefcount(AgentDBEntry *e)
Definition: agent_db.h:183
boost::intrusive_ptr< DBTableWalk > DBTableWalkRef
Definition: db_table.h:169
void Notify(DBEntryBase *entry)
DBTable::DBTableWalkRef flush_walk_ref_
Definition: agent_db.h:225
virtual void Remove(DBEntryBase *entry)
virtual void Input(DBTablePartition *root, DBClient *client, DBRequest *req)
Definition: agent_db.cc:188
ResourceManager * resource_manager() const
Definition: agent.cc:1021
virtual void Input(DBTablePartition *tbl_partition, DBClient *client, DBRequest *req)
Definition: db_table.cc:516
SandeshTraceBufferPtr SandeshTraceBufferCreate(const std::string &buf_name, size_t buf_size, bool trace_enable=true)
Definition: sandesh_trace.h:46