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-11-09 02:10:49 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             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #include "db/db_entry.h"
       7             : 
       8             : #include <tbb/mutex.h>
       9             : 
      10             : #include "base/time_util.h"
      11             : #include "db/db_table_partition.h"
      12             : 
      13             : using namespace std;
      14             : 
      15     9778384 : DBEntryBase::DBEntryBase()
      16     9778384 :         : tpart_(NULL), flags(0), last_change_at_(UTCTimestampUsec()) {
      17     9780725 :     onremoveq_ = false;
      18     9781443 : }
      19             : 
      20     9772228 : DBEntryBase::~DBEntryBase() {
      21     9772228 : }
      22             : 
      23     3755799 : void DBEntryBase::SetState(DBTableBase *tbl_base, ListenerId listener,
      24             :                            DBState *state) {
      25     3755799 :     DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
      26     3755700 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), true);
      27     3757687 :     pair<StateMap::iterator, bool> res = state_.insert(
      28     3757070 :         make_pair(listener, state));
      29     3757295 :     if (!res.second) {
      30     1230928 :         res.first->second = state;
      31             :     } else {
      32     2526367 :         assert(!IsDeleted());
      33             :         // Account for state addition for this listener.
      34     2526379 :         tbl_base->AddToDBStateCount(listener, 1);
      35             :     }
      36     3757133 : }
      37             : 
      38    12479332 : DBState *DBEntryBase::GetState(DBTableBase *tbl_base, ListenerId listener) const {
      39    12479332 :     DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
      40    12475760 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), false);
      41    12487415 :     StateMap::const_iterator loc = state_.find(listener);
      42    12471032 :     if (loc != state_.end()) {
      43     8001769 :         return loc->second;
      44             :     }
      45     4472858 :     return NULL;
      46    12474313 : }
      47             : 
      48         759 : const DBState *DBEntryBase::GetState(const DBTableBase *tbl_base,
      49             :                                      ListenerId listener) const {
      50         759 :     DBTableBase *table = const_cast<DBTableBase *>(tbl_base);
      51         759 :     DBTablePartBase *tpart = table->GetTablePartition(this);
      52         759 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), false);
      53         759 :     StateMap::const_iterator loc = state_.find(listener);
      54         759 :     if (loc != state_.end()) {
      55         732 :         return loc->second;
      56             :     }
      57          27 :     return NULL;
      58         759 : }
      59             : 
      60             : //
      61             : // Concurrency: called from arbitrary task.
      62             : //
      63             : // Evaluate concurrency issues with DBTablePartBase::RunNotify when making
      64             : // changes to this method.  We expect that either this method or RunNotify
      65             : // is responsible for removing the DBEntryBase when they run concurrently,
      66             : // assuming the DBEntryBase is eligible for removal.  The dbstate_mutex in
      67             : // in DBTablePartBase is used for synchronization.
      68             : //
      69             : // Remove DBState on this DBEntryBase for the given listener and enqueue
      70             : // for removal if appropriate.
      71             : // Note that the entry cannot be removed from DBTablePartBase here since
      72             : // this method may be called from an arbitrary Task.
      73             : //
      74     2525689 : void DBEntryBase::ClearState(DBTableBase *tbl_base, ListenerId listener) {
      75     2525689 :     DBTablePartBase *tpart = tbl_base->GetTablePartition(this);
      76     2525582 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), true);
      77             : 
      78     2526253 :     assert(state_.erase(listener) != 0);
      79             : 
      80             :     // Account for state removal for this listener.
      81     2525629 :     tbl_base->AddToDBStateCount(listener, -1);
      82             : 
      83     2526364 :     if (state_.empty() && IsDeleted() && !is_onlist() && !IsOnRemoveQ()) {
      84      524815 :         tbl_base->EnqueueRemove(this);
      85             :     }
      86     2526321 : }
      87             : 
      88     1071206 : bool DBEntryBase::is_state_empty(DBTablePartBase *tpart) {
      89     1071206 :     tbb::spin_rw_mutex::scoped_lock lock(tpart->dbstate_mutex(), false);
      90     2142376 :     return state_.empty();
      91     1071085 : }
      92             : 
      93      524791 : bool DBEntryBase::is_state_empty_unlocked(DBTablePartBase *tpart) {
      94      524791 :     return state_.empty();
      95             : }
      96             : 
      97     2198135 : void DBEntryBase::set_last_change_at_to_now() {
      98     2198135 :     last_change_at_ = UTCTimestampUsec();
      99     2198214 : }
     100             : 
     101           0 : void DBEntryBase::set_last_change_at(uint64_t time) {
     102           0 :     last_change_at_ = time;
     103           0 : }
     104             : 
     105     2329974 : void DBEntryBase::set_last_update_at_to_now() {
     106     2329974 :     last_update_at_ = UTCTimestampUsec();
     107     2330037 : }
     108             : 
     109         152 : void DBEntryBase::set_last_update_at(uint64_t time) {
     110         152 :     last_update_at_ = time;
     111         152 : }
     112     1449462 : void DBEntryBase::set_table_partition(DBTablePartBase *tpart) {
     113     1449462 :     tpart_ = tpart;
     114     1449462 : }
     115             : 
     116     3278380 : DBTablePartBase *DBEntryBase::get_table_partition() const {
     117     3278380 :     return tpart_;
     118             : }
     119             : 
     120     9760772 : DBTableBase *DBEntryBase::get_table() const {
     121     9760772 :     return (tpart_ ? tpart_->parent() : NULL);
     122             : }
     123             : 
     124           0 : const std::string DBEntryBase::last_change_at_str() const {
     125           0 :     return duration_usecs_to_string(UTCTimestampUsec() - last_change_at_);
     126             : }
     127             : 
     128       60154 : void DBEntryBase::Notify() {
     129       60154 :     tpart_->Notify(this);
     130       60154 : }
     131             : 
     132       48076 : void DBEntryBase::Delete() {
     133       48076 :     if (!IsDeleted())
     134       48076 :         tpart_->Delete(this);
     135       48076 : }

Generated by: LCOV version 1.14