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

Generated by: LCOV version 1.14