LCOV - code coverage report
Current view: top level - db - db_entry.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 70 75 93.3 %
Date: 2026-06-18 01:51:13 Functions: 16 19 84.2 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
      14     9483826 : DBEntryBase::DBEntryBase()
      15     9483826 :         : tpart_(NULL), flags(0), last_change_at_(UTCTimestampUsec()) {
      16     9484777 :     onremoveq_ = false;
      17     9484745 : }
      18             : 
      19     9466837 : DBEntryBase::~DBEntryBase() {
      20     9466837 : }
      21             : 
      22     3692147 : void DBEntryBase::SetState(DBTableBase *tbl_base, ListenerId listener,
      23             :                            DBState *state) {
      24     3692147 :     DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
      25     3692414 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), true);
      26     3693916 :     pair<StateMap::iterator, bool> res = state_.insert(
      27     3693865 :         make_pair(listener, state));
      28     3693755 :     if (!res.second) {
      29     1223039 :         res.first->second = state;
      30             :     } else {
      31     2470716 :         assert(!IsDeleted());
      32             :         // Account for state addition for this listener.
      33     2470741 :         tbl_base->AddToDBStateCount(listener, 1);
      34             :     }
      35     3693658 : }
      36             : 
      37    12174045 : DBState *DBEntryBase::GetState(DBTableBase *tbl_base, ListenerId listener) const {
      38    12174045 :     DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
      39    12170711 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), false);
      40    12182774 :     StateMap::const_iterator loc = state_.find(listener);
      41    12168253 :     if (loc != state_.end()) {
      42     7811571 :         return loc->second;
      43             :     }
      44     4359298 :     return NULL;
      45    12170415 : }
      46             : 
      47         795 : const DBState *DBEntryBase::GetState(const DBTableBase *tbl_base,
      48             :                                      ListenerId listener) const {
      49         795 :     DBTableBase *table = const_cast<DBTableBase *>(tbl_base);
      50         795 :     DBTablePartBase *tpart = table->GetTablePartition(this);
      51         795 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), false);
      52         795 :     StateMap::const_iterator loc = state_.find(listener);
      53         795 :     if (loc != state_.end()) {
      54         768 :         return loc->second;
      55             :     }
      56          27 :     return NULL;
      57         795 : }
      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     2470106 : void DBEntryBase::ClearState(DBTableBase *tbl_base, ListenerId listener) {
      74     2470106 :     DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
      75     2469932 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), true);
      76             : 
      77     2470688 :     assert(state_.erase(listener) != 0);
      78             : 
      79             :     // Account for state removal for this listener.
      80     2469838 :     tbl_base->AddToDBStateCount(listener, -1);
      81             : 
      82     2470640 :     if (state_.empty() && IsDeleted() && !is_onlist() && !IsOnRemoveQ()) {
      83      513724 :         tbl_base->EnqueueRemove(this);
      84             :     }
      85     2470602 : }
      86             : 
      87     1057694 : bool DBEntryBase::is_state_empty(DBTablePartBase *tpart) {
      88     1057694 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), false);
      89     2115437 :     return state_.empty();
      90     1057659 : }
      91             : 
      92      513709 : bool DBEntryBase::is_state_empty_unlocked(DBTablePartBase *tpart) {
      93      513709 :     return state_.empty();
      94             : }
      95             : 
      96     2186721 : void DBEntryBase::set_last_change_at_to_now() {
      97     2186721 :     last_change_at_ = UTCTimestampUsec();
      98     2186772 : }
      99             : 
     100           0 : void DBEntryBase::set_last_change_at(uint64_t time) {
     101           0 :     last_change_at_ = time;
     102           0 : }
     103             : 
     104     2302143 : void DBEntryBase::set_last_update_at_to_now() {
     105     2302143 :     last_update_at_ = UTCTimestampUsec();
     106     2302164 : }
     107             : 
     108         150 : void DBEntryBase::set_last_update_at(uint64_t time) {
     109         150 :     last_update_at_ = time;
     110         150 : }
     111     1431161 : void DBEntryBase::set_table_partition(DBTablePartBase *tpart) {
     112     1431161 :     tpart_ = tpart;
     113     1431161 : }
     114             : 
     115     3205932 : DBTablePartBase *DBEntryBase::get_table_partition() const {
     116     3205932 :     return tpart_;
     117             : }
     118             : 
     119     9303654 : DBTableBase *DBEntryBase::get_table() const {
     120     9303654 :     return (tpart_ ? tpart_->parent() : NULL);
     121             : }
     122             : 
     123           0 : const std::string DBEntryBase::last_change_at_str() const {
     124           0 :     return duration_usecs_to_string(UTCTimestampUsec() - last_change_at_);
     125             : }
     126             : 
     127       60141 : void DBEntryBase::Notify() {
     128       60141 :     tpart_->Notify(this);
     129       60141 : }
     130             : 
     131       48078 : void DBEntryBase::Delete() {
     132       48078 :     if (!IsDeleted())
     133       48078 :         tpart_->Delete(this);
     134       48078 : }

Generated by: LCOV version 1.14