OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
db_entry.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include "db/db_entry.h"
6 
7 #include <tbb/mutex.h>
8 
9 #include "base/time_util.h"
10 #include "db/db_table_partition.h"
11 
12 using namespace std;
13 
15  : tpart_(NULL), flags(0), last_change_at_(UTCTimestampUsec()) {
16  onremoveq_ = false;
17 }
18 
20 }
21 
22 void DBEntryBase::SetState(DBTableBase *tbl_base, ListenerId listener,
23  DBState *state) {
24  DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
25  tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), true);
26  pair<StateMap::iterator, bool> res = state_.insert(
27  make_pair(listener, state));
28  if (!res.second) {
29  res.first->second = state;
30  } else {
31  assert(!IsDeleted());
32  // Account for state addition for this listener.
33  tbl_base->AddToDBStateCount(listener, 1);
34  }
35 }
36 
37 DBState *DBEntryBase::GetState(DBTableBase *tbl_base, ListenerId listener) const {
38  DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
39  tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), false);
40  StateMap::const_iterator loc = state_.find(listener);
41  if (loc != state_.end()) {
42  return loc->second;
43  }
44  return NULL;
45 }
46 
47 const DBState *DBEntryBase::GetState(const DBTableBase *tbl_base,
48  ListenerId listener) const {
49  DBTableBase *table = const_cast<DBTableBase *>(tbl_base);
50  DBTablePartBase *tpart = table->GetTablePartition(this);
51  tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), false);
52  StateMap::const_iterator loc = state_.find(listener);
53  if (loc != state_.end()) {
54  return loc->second;
55  }
56  return NULL;
57 }
58 
59 //
60 // Concurrency: called from arbitrary task.
61 //
62 // Evaluate concurrency issues with DBTablePartBase::RunNotify when making
63 // changes to this method. We expect that either this method or RunNotify
64 // is responsible for removing the DBEntryBase when they run concurrently,
65 // assuming the DBEntryBase is eligible for removal. The dbstate_mutex in
66 // in DBTablePartBase is used for synchronization.
67 //
68 // Remove DBState on this DBEntryBase for the given listener and enqueue
69 // for removal if appropriate.
70 // Note that the entry cannot be removed from DBTablePartBase here since
71 // this method may be called from an arbitrary Task.
72 //
73 void DBEntryBase::ClearState(DBTableBase *tbl_base, ListenerId listener) {
74  DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
75  tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), true);
76 
77  assert(state_.erase(listener) != 0);
78 
79  // Account for state removal for this listener.
80  tbl_base->AddToDBStateCount(listener, -1);
81 
82  if (state_.empty() && IsDeleted() && !is_onlist() && !IsOnRemoveQ()) {
83  tbl_base->EnqueueRemove(this);
84  }
85 }
86 
88  tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), false);
89  return state_.empty();
90 }
91 
93  return state_.empty();
94 }
95 
98 }
99 
100 void DBEntryBase::set_last_change_at(uint64_t time) {
101  last_change_at_ = time;
102 }
103 
106 }
107 
108 void DBEntryBase::set_last_update_at(uint64_t time) {
109  last_update_at_ = time;
110 }
112  tpart_ = tpart;
113 }
114 
116  return tpart_;
117 }
118 
120  return (tpart_ ? tpart_->parent() : NULL);
121 }
122 
123 const std::string DBEntryBase::last_change_at_str() const {
125 }
126 
128  tpart_->Notify(this);
129 }
130 
132  if (!IsDeleted())
133  tpart_->Delete(this);
134 }
tbb::spin_rw_mutex & dbstate_mutex()
uint64_t last_update_at_
Definition: db_entry.h:89
void set_last_update_at(uint64_t time)
Definition: db_entry.cc:108
void set_last_update_at_to_now()
Definition: db_entry.cc:104
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
Definition: db_entry.cc:37
DBTableBase * get_table() const
Definition: db_entry.cc:119
void AddToDBStateCount(ListenerId listener, int count)
Definition: db_table.cc:212
void set_last_change_at_to_now()
Definition: db_entry.cc:96
bool IsDeleted() const
Definition: db_entry.h:49
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
Definition: db_entry.cc:22
DBTableBase * parent()
const std::string last_change_at_str() const
Definition: db_entry.cc:123
void Delete(DBEntryBase *)
StateMap state_
Definition: db_entry.h:85
bool IsOnRemoveQ()
Definition: db_entry.h:58
tbb::atomic< bool > onremoveq_
Definition: db_entry.h:87
static const std::string duration_usecs_to_string(const uint64_t usecs)
Definition: time_util.h:62
void set_table_partition(DBTablePartBase *tpart)
Definition: db_entry.cc:111
bool is_state_empty(DBTablePartBase *tpart)
Definition: db_entry.cc:87
DBTablePartBase * tpart_
Definition: db_entry.h:84
void EnqueueRemove(DBEntryBase *db_entry)
Definition: db_table.cc:201
void ClearState(DBTableBase *tbl_base, ListenerId listener)
Definition: db_entry.cc:73
bool is_state_empty_unlocked(DBTablePartBase *tpart)
Definition: db_entry.cc:92
void Delete()
Definition: db_entry.cc:131
uint64_t last_change_at_
Definition: db_entry.h:88
static uint64_t UTCTimestampUsec()
Definition: time_util.h:13
bool is_onlist()
Definition: db_entry.h:53
void set_last_change_at(uint64_t time)
Definition: db_entry.cc:100
void Notify()
Definition: db_entry.cc:127
DBTablePartBase * get_table_partition() const
Definition: db_entry.cc:115
void Notify(DBEntryBase *entry)
virtual ~DBEntryBase()
Definition: db_entry.cc:19
DBTableBase::ListenerId ListenerId
Definition: db_entry.h:24
virtual DBTablePartBase * GetTablePartition(const DBRequestKey *key)=0