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-21 02:11:39 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     9566658 : DBEntryBase::DBEntryBase()
      15     9566658 :         : tpart_(NULL), flags(0), last_change_at_(UTCTimestampUsec()) {
      16     9573599 :     onremoveq_ = false;
      17     9575104 : }
      18             : 
      19     9549806 : DBEntryBase::~DBEntryBase() {
      20     9549806 : }
      21             : 
      22     3716774 : void DBEntryBase::SetState(DBTableBase *tbl_base, ListenerId listener,
      23             :                            DBState *state) {
      24     3716774 :     DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
      25     3717138 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), true);
      26     3718993 :     pair<StateMap::iterator, bool> res = state_.insert(
      27     3718417 :         make_pair(listener, state));
      28     3718241 :     if (!res.second) {
      29     1225088 :         res.first->second = state;
      30             :     } else {
      31     2493153 :         assert(!IsDeleted());
      32             :         // Account for state addition for this listener.
      33     2493081 :         tbl_base->AddToDBStateCount(listener, 1);
      34             :     }
      35     3718062 : }
      36             : 
      37    12213423 : DBState *DBEntryBase::GetState(DBTableBase *tbl_base, ListenerId listener) const {
      38    12213423 :     DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
      39    12212434 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), false);
      40    12222268 :     StateMap::const_iterator loc = state_.find(listener);
      41    12207842 :     if (loc != state_.end()) {
      42     7815095 :         return loc->second;
      43             :     }
      44     4396583 :     return NULL;
      45    12211374 : }
      46             : 
      47         761 : const DBState *DBEntryBase::GetState(const DBTableBase *tbl_base,
      48             :                                      ListenerId listener) const {
      49         761 :     DBTableBase *table = const_cast<DBTableBase *>(tbl_base);
      50         761 :     DBTablePartBase *tpart = table->GetTablePartition(this);
      51         761 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), false);
      52         761 :     StateMap::const_iterator loc = state_.find(listener);
      53         761 :     if (loc != state_.end()) {
      54         734 :         return loc->second;
      55             :     }
      56          27 :     return NULL;
      57         761 : }
      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     2492801 : void DBEntryBase::ClearState(DBTableBase *tbl_base, ListenerId listener) {
      74     2492801 :     DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
      75     2492640 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), true);
      76             : 
      77     2493284 :     assert(state_.erase(listener) != 0);
      78             : 
      79             :     // Account for state removal for this listener.
      80     2492527 :     tbl_base->AddToDBStateCount(listener, -1);
      81             : 
      82     2493211 :     if (state_.empty() && IsDeleted() && !is_onlist() && !IsOnRemoveQ()) {
      83      518782 :         tbl_base->EnqueueRemove(this);
      84             :     }
      85     2493219 : }
      86             : 
      87     1058303 : bool DBEntryBase::is_state_empty(DBTablePartBase *tpart) {
      88     1058303 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), false);
      89     2118583 :     return state_.empty();
      90     1059139 : }
      91             : 
      92      518823 : bool DBEntryBase::is_state_empty_unlocked(DBTablePartBase *tpart) {
      93      518823 :     return state_.empty();
      94             : }
      95             : 
      96     2188658 : void DBEntryBase::set_last_change_at_to_now() {
      97     2188658 :     last_change_at_ = UTCTimestampUsec();
      98     2188757 : }
      99             : 
     100           0 : void DBEntryBase::set_last_change_at(uint64_t time) {
     101           0 :     last_change_at_ = time;
     102           0 : }
     103             : 
     104     2310683 : void DBEntryBase::set_last_update_at_to_now() {
     105     2310683 :     last_update_at_ = UTCTimestampUsec();
     106     2310784 : }
     107             : 
     108         150 : void DBEntryBase::set_last_update_at(uint64_t time) {
     109         150 :     last_update_at_ = time;
     110         150 : }
     111     1433694 : void DBEntryBase::set_table_partition(DBTablePartBase *tpart) {
     112     1433694 :     tpart_ = tpart;
     113     1433694 : }
     114             : 
     115     3253756 : DBTablePartBase *DBEntryBase::get_table_partition() const {
     116     3253756 :     return tpart_;
     117             : }
     118             : 
     119     9419306 : DBTableBase *DBEntryBase::get_table() const {
     120     9419306 :     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       60166 : void DBEntryBase::Notify() {
     128       60166 :     tpart_->Notify(this);
     129       60166 : }
     130             : 
     131       48078 : void DBEntryBase::Delete() {
     132       48078 :     if (!IsDeleted())
     133       48078 :         tpart_->Delete(this);
     134       48078 : }

Generated by: LCOV version 1.14