LCOV - code coverage report
Current view: top level - vnsw/agent/cmn - agent_db.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 44 56 78.6 %
Date: 2026-11-09 02:10:49 Functions: 100 187 53.5 %
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             : #ifndef vnsw_agent_db_hpp
       7             : #define vnsw_agent_db_hpp
       8             : 
       9             : #include <atomic>
      10             : #include <mutex>
      11             : #include <cmn/agent_cmn.h>
      12             : 
      13             : class Agent;
      14             : class AgentDBEntry;
      15             : class AgentDBTable;
      16             : struct AgentDBState;
      17             : class AgentSandesh;
      18             : class AgentSandeshArguments;
      19             : class AgentSandesh;
      20             : class ResourceManager;
      21             : typedef class boost::shared_ptr<AgentSandesh> AgentSandeshPtr;
      22             : 
      23             : /////////////////////////////////////////////////////////////////////////////
      24             : // Refcount class for AgentDBEntry
      25             : /////////////////////////////////////////////////////////////////////////////
      26             : template <class Derived>
      27             : class AgentRefCount {
      28             : public:
      29       82366 :     friend void intrusive_ptr_add_ref(const Derived* p) {
      30       82366 :         const AgentRefCount *entry = (const AgentRefCount *) (p);
      31      164732 :         if (entry->refcount_.fetch_add(1) == 0) {
      32        3203 :             p->SetRefState();
      33             :         }
      34       82366 :     }
      35             : 
      36       82366 :     friend void intrusive_ptr_release(const Derived* p) {
      37       82366 :         const AgentRefCount *entry = (const AgentRefCount *) (p);
      38      164732 :         if (entry->refcount_.fetch_sub(1) == 1) {
      39        3203 :             p->ClearRefState();
      40             :         }
      41       82366 :     }
      42             : 
      43       19387 :     friend void intrusive_ptr_add_back_ref(const IntrusiveReferrer ref,
      44             :                                            const Derived* p) {
      45       19387 :         const AgentRefCount *entry = (const AgentRefCount *) (p);
      46       19387 :         std::scoped_lock lock(entry->back_ref_mutex_);
      47       19387 :         entry->back_ref_set_.insert(ref);
      48       19387 :     }
      49             : 
      50       35219 :     friend void intrusive_ptr_del_back_ref(const IntrusiveReferrer ref,
      51             :                                            const Derived* p) {
      52       35219 :         const AgentRefCount *entry = (const AgentRefCount *) (p);
      53       35219 :         std::scoped_lock lock(entry->back_ref_mutex_);
      54       35219 :         entry->back_ref_set_.erase(ref);
      55       35219 :     }
      56             : 
      57        4177 :     uint32_t GetRefCount() const {return refcount_;};
      58             : protected:
      59      430253 :     AgentRefCount() {refcount_ = 0;}
      60             :     AgentRefCount(const AgentRefCount&) { refcount_ = 0; }
      61             :     AgentRefCount& operator=(const AgentRefCount&) { return *this; }
      62      429763 :     virtual ~AgentRefCount() {assert(refcount_ == 0);};
      63             :     void swap(AgentRefCount&) {};
      64             : 
      65             :     mutable std::mutex back_ref_mutex_;
      66             :     mutable std::set<IntrusiveReferrer> back_ref_set_;
      67             : 
      68             : private:
      69             :     mutable std::atomic<uint32_t> refcount_;
      70             : };
      71             : 
      72             : /////////////////////////////////////////////////////////////////////////////
      73             : // DBState for AgentDBEntry
      74             : /////////////////////////////////////////////////////////////////////////////
      75             : struct AgentDBState : DBState {
      76        3198 :     AgentDBState(const AgentDBEntry *entry) : DBState(), entry_(entry) { };
      77             :     const AgentDBEntry *entry_;
      78             : };
      79             : 
      80             : /////////////////////////////////////////////////////////////////////////////
      81             : // VNSwitch DB Table Partition class
      82             : /////////////////////////////////////////////////////////////////////////////
      83             : class AgentDBTablePartition: public DBTablePartition {
      84             : public:
      85          48 :     AgentDBTablePartition(DBTable *parent, int index) :
      86          48 :         DBTablePartition(parent, index) { };
      87          96 :     virtual ~AgentDBTablePartition() {};
      88             :     virtual void Add(DBEntry *entry);
      89             :     virtual void Remove(DBEntryBase *entry);
      90             : 
      91             : private:
      92             :     DISALLOW_COPY_AND_ASSIGN(AgentDBTablePartition);
      93             : };
      94             : 
      95             : /////////////////////////////////////////////////////////////////////////////
      96             : // VNSwitch DB Entry Key base class. Defines additional operations on DBEntry
      97             : /////////////////////////////////////////////////////////////////////////////
      98             : struct AgentKey : public DBRequestKey {
      99             :     typedef enum {
     100             :         // Add/Delete/Change a entry
     101             :         ADD_DEL_CHANGE,
     102             :         // Change an entry if its already present and not in deleted state
     103             :         // Its a no-op if entry is not present or is in deleted state
     104             :         RESYNC,
     105             :     } DBSubOperation;
     106             : 
     107      117298 :     AgentKey() : DBRequestKey(), sub_op_(ADD_DEL_CHANGE) { };
     108       53795 :     AgentKey(DBSubOperation sub_op) : DBRequestKey(), sub_op_(sub_op) { };
     109      169817 :     virtual ~AgentKey() { };
     110             : 
     111             :     uint8_t sub_op_;
     112             : };
     113             : 
     114             : /////////////////////////////////////////////////////////////////////////////
     115             : // VNSwitch DB Entry Data base class
     116             : /////////////////////////////////////////////////////////////////////////////
     117             : struct AgentData : public DBRequestData {
     118       27281 :     AgentData() : DBRequestData() { };
     119       27281 :     virtual ~AgentData() { };
     120             : };
     121             : 
     122             : /////////////////////////////////////////////////////////////////////////////
     123             : // VNSwitch DB Entry base class. Supports
     124             : // 1. Reference counting with boost Intrusive pointer
     125             : /////////////////////////////////////////////////////////////////////////////
     126             : class AgentDBEntry : public DBEntry {
     127             : public:
     128      111960 :     AgentDBEntry() : DBEntry() {};
     129      111960 :     virtual ~AgentDBEntry() {};
     130             :     virtual uint32_t GetRefCount() const = 0;
     131             : 
     132             :     typedef boost::intrusive_ptr<AgentDBEntry> AgentDBEntyRef;
     133             :     void SetRefState() const;
     134             :     void ClearRefState() const;
     135             :     bool IsActive() const;
     136             :     DBState *GetAgentDBEntryState(int listener_id);
     137             :     const DBState *GetAgentDBEntryState(int listener_id) const;
     138             : 
     139             :     virtual void AllocateResources(ResourceManager *resource_manager);
     140             :     virtual void FreeResources(ResourceManager *resource_manager);
     141             :     virtual void PostAdd();
     142             :     virtual bool DBEntrySandesh(Sandesh *resp, std::string &name) const = 0;
     143             : private:
     144             :     friend class AgentDBTable;
     145             :     DISALLOW_COPY_AND_ASSIGN(AgentDBEntry);
     146             : };
     147             : 
     148             : /////////////////////////////////////////////////////////////////////////////
     149             : // VNSwitch DB Table base class
     150             : /////////////////////////////////////////////////////////////////////////////
     151             : class AgentDBTable : public DBTable {
     152             : public:
     153             :     static const int kPartitionCount = 1;
     154             :     AgentDBTable(DB *db, const std::string &name);
     155             :     AgentDBTable(DB *db, const std::string &name, bool del_on_zero_refcount);
     156             :     virtual ~AgentDBTable();
     157             : 
     158         438 :     virtual int PartitionCount() const { return kPartitionCount; }
     159             :     virtual void Input(DBTablePartition *root, DBClient *client,
     160             :                        DBRequest *req);
     161           0 :     virtual DBEntry *CfgAdd(DBRequest *req) {return NULL;};
     162           0 :     virtual bool Resync(DBEntry *entry, const DBRequest *req) {return false;};
     163             : 
     164             :     /*
     165             :      * Clear all entries on a table. Requires the table to have no listeners.
     166             :      * Used in process shutdown.
     167             :      */
     168             :     virtual void Clear();
     169             : 
     170           0 :     virtual bool IFNodeToReq(IFMapNode *node, DBRequest &req,
     171             :             const boost::uuids::uuid &uuid) {
     172           0 :         assert(0);
     173             :         return false;
     174             :     }
     175           0 :     virtual bool IFLinkToReq(IFMapLink *link, IFMapNode *node,
     176             :                              const std::string &peer_name, IFMapNode *peer,
     177             :                              DBRequest &req) {
     178           0 :         assert(0);
     179             :         return false;
     180             :     }
     181             :     virtual bool IFNodeToUuid(IFMapNode *node, boost::uuids::uuid &id);
     182             : 
     183          48 :     virtual DBTablePartition *AllocPartition(int index) {
     184          48 :         return new AgentDBTablePartition(this, index);
     185             :     };
     186         424 :     virtual void OnZeroRefcount(AgentDBEntry *e) {};
     187             :     virtual void NotifyEntry(DBEntryBase *entry);
     188             : 
     189           0 :     virtual AgentSandeshPtr GetAgentSandesh(const AgentSandeshArguments *args,
     190             :                                             const std::string &context) {
     191           0 :         return AgentSandeshPtr();
     192             :     }
     193             : 
     194             :     // Dummy notification
     195        8675 :     void Notify(DBTablePartBase *partition, DBEntryBase *entry) {
     196        8675 :     };
     197             : 
     198        9594 :     DBTableBase::ListenerId GetRefListenerId() const {return ref_listener_id_;};
     199             :     AgentDBEntry *FindActiveEntry(const DBEntry *key);
     200             :     AgentDBEntry *FindActiveEntryNoLock(const DBEntry *key);
     201             :     AgentDBEntry *FindActiveEntry(const DBRequestKey *key);
     202             :     AgentDBEntry *FindActiveEntryNoLock(const DBRequestKey *key);
     203             :     AgentDBEntry *Find(const DBEntry *key, bool ret_del);
     204             :     AgentDBEntry *Find(const DBRequestKey *key, bool ret_del);
     205           0 :     virtual bool CanNotify(IFMapNode *dbe) {
     206           0 :         return true;
     207             :     }
     208             :     virtual void Process(DBRequest &req);
     209           0 :     virtual bool ProcessConfig(IFMapNode *node, DBRequest &req,
     210             :             const boost::uuids::uuid &u) {
     211           0 :         assert(0);
     212             :         return false;
     213             :     }
     214             : 
     215          48 :     void set_agent(Agent *agent) { agent_ = agent; }
     216      137788 :     Agent *agent() const { return agent_; }
     217             : 
     218             :     void Flush();
     219             :     void reset_flush_walk_ref();
     220       16745 :     SandeshTraceBufferPtr GetOperDBTraceBuf() const {return OperDBTraceBuf;}
     221             : private:
     222             :     AgentDBEntry *Find(const DBEntry *key);
     223             :     AgentDBEntry *Find(const DBRequestKey *key);
     224             : 
     225             :     DBTableBase::ListenerId ref_listener_id_;
     226             :     Agent *agent_;
     227             :     SandeshTraceBufferPtr OperDBTraceBuf;
     228             :     DBTable::DBTableWalkRef flush_walk_ref_;
     229             :     DISALLOW_COPY_AND_ASSIGN(AgentDBTable);
     230             : };
     231             : 
     232             : #define OPER_TRACE(obj, ...)\
     233             : do {\
     234             :    Oper##obj::TraceMsg(GetOperDBTraceBuf(), __FILE__, __LINE__, __VA_ARGS__);\
     235             : } while (false)
     236             : 
     237             : #define OPER_TRACE_ENTRY(obj, table, ...)\
     238             : do {\
     239             :    Oper##obj::TraceMsg(table->GetOperDBTraceBuf(),\
     240             :                        __FILE__, __LINE__, __VA_ARGS__);\
     241             : } while (false)
     242             : 
     243             : #endif // vnsw_agent_db_hpp

Generated by: LCOV version 1.14