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-09-28 02:13:17 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     9569848 : DBEntryBase::DBEntryBase()
      15     9569848 :         : tpart_(NULL), flags(0), last_change_at_(UTCTimestampUsec()) {
      16     9575249 :     onremoveq_ = false;
      17     9575101 : }
      18             : 
      19     9560870 : DBEntryBase::~DBEntryBase() {
      20     9560870 : }
      21             : 
      22     3716252 : void DBEntryBase::SetState(DBTableBase *tbl_base, ListenerId listener,
      23             :                            DBState *state) {
      24     3716252 :     DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
      25     3716306 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), true);
      26     3717401 :     pair<StateMap::iterator, bool> res = state_.insert(
      27     3717055 :         make_pair(listener, state));
      28     3717042 :     if (!res.second) {
      29     1226471 :         res.first->second = state;
      30             :     } else {
      31     2490571 :         assert(!IsDeleted());
      32             :         // Account for state addition for this listener.
      33     2490613 :         tbl_base->AddToDBStateCount(listener, 1);
      34             :     }
      35     3716990 : }
      36             : 
      37    12242417 : DBState *DBEntryBase::GetState(DBTableBase *tbl_base, ListenerId listener) const {
      38    12242417 :     DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
      39    12240727 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), false);
      40    12246679 :     StateMap::const_iterator loc = state_.find(listener);
      41    12237721 :     if (loc != state_.end()) {
      42     7847432 :         return loc->second;
      43             :     }
      44     4392722 :     return NULL;
      45    12239955 : }
      46             : 
      47         769 : const DBState *DBEntryBase::GetState(const DBTableBase *tbl_base,
      48             :                                      ListenerId listener) const {
      49         769 :     DBTableBase *table = const_cast<DBTableBase *>(tbl_base);
      50         769 :     DBTablePartBase *tpart = table->GetTablePartition(this);
      51         769 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), false);
      52         769 :     StateMap::const_iterator loc = state_.find(listener);
      53         769 :     if (loc != state_.end()) {
      54         739 :         return loc->second;
      55             :     }
      56          30 :     return NULL;
      57         769 : }
      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     2490195 : void DBEntryBase::ClearState(DBTableBase *tbl_base, ListenerId listener) {
      74     2490195 :     DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
      75     2490037 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), true);
      76             : 
      77     2490546 :     assert(state_.erase(listener) != 0);
      78             : 
      79             :     // Account for state removal for this listener.
      80     2489997 :     tbl_base->AddToDBStateCount(listener, -1);
      81             : 
      82     2490542 :     if (state_.empty() && IsDeleted() && !is_onlist() && !IsOnRemoveQ()) {
      83      517180 :         tbl_base->EnqueueRemove(this);
      84             :     }
      85     2490493 : }
      86             : 
      87     1060234 : bool DBEntryBase::is_state_empty(DBTablePartBase *tpart) {
      88     1060234 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), false);
      89     2120483 :     return state_.empty();
      90     1060054 : }
      91             : 
      92      517117 : bool DBEntryBase::is_state_empty_unlocked(DBTablePartBase *tpart) {
      93      517117 :     return state_.empty();
      94             : }
      95             : 
      96     2191708 : void DBEntryBase::set_last_change_at_to_now() {
      97     2191708 :     last_change_at_ = UTCTimestampUsec();
      98     2191803 : }
      99             : 
     100           0 : void DBEntryBase::set_last_change_at(uint64_t time) {
     101           0 :     last_change_at_ = time;
     102           0 : }
     103             : 
     104     2313226 : void DBEntryBase::set_last_update_at_to_now() {
     105     2313226 :     last_update_at_ = UTCTimestampUsec();
     106     2313291 : }
     107             : 
     108         150 : void DBEntryBase::set_last_update_at(uint64_t time) {
     109         150 :     last_update_at_ = time;
     110         150 : }
     111     1434534 : void DBEntryBase::set_table_partition(DBTablePartBase *tpart) {
     112     1434534 :     tpart_ = tpart;
     113     1434534 : }
     114             : 
     115     3232871 : DBTablePartBase *DBEntryBase::get_table_partition() const {
     116     3232871 :     return tpart_;
     117             : }
     118             : 
     119     9436425 : DBTableBase *DBEntryBase::get_table() const {
     120     9436425 :     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       60138 : void DBEntryBase::Notify() {
     128       60138 :     tpart_->Notify(this);
     129       60138 : }
     130             : 
     131       48074 : void DBEntryBase::Delete() {
     132       48074 :     if (!IsDeleted())
     133       48074 :         tpart_->Delete(this);
     134       48074 : }

Generated by: LCOV version 1.14