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 ctrlplane_db_entry_h 7 : #define ctrlplane_db_entry_h 8 : 9 : #include <map> 10 : #include <atomic> 11 : 12 : #include "db/db_table.h" 13 : 14 : #include <boost/intrusive/list.hpp> 15 : #include <boost/intrusive/set.hpp> 16 : 17 : struct DBState { 18 3170853 : virtual ~DBState() { } 19 : }; 20 : 21 : // Generic database entry 22 : class DBEntryBase { 23 : public: 24 : typedef DBTableBase::ListenerId ListenerId; 25 : typedef std::unique_ptr<DBRequestKey> KeyPtr; 26 : 27 : DBEntryBase(); 28 : virtual ~DBEntryBase(); 29 : virtual std::string ToString() const = 0; 30 : virtual KeyPtr GetDBRequestKey() const = 0; 31 13 : virtual bool IsMoreSpecific(const std::string &match) const { 32 13 : return false; 33 : } 34 10 : virtual bool IsLessSpecific(const std::string &match) const { 35 10 : return false; 36 : } 37 : 38 : void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state); 39 : void ClearState(DBTableBase *tbl_base, ListenerId listener); 40 : DBState *GetState(DBTableBase *tbl_base, ListenerId listener) const; 41 : const DBState *GetState(const DBTableBase *tbl_base, 42 : ListenerId listener) const; 43 : bool is_state_empty(DBTablePartBase *tpart); 44 : bool is_state_empty_unlocked(DBTablePartBase *tpart); 45 : 46 : void Delete(); 47 863855 : void MarkDelete() { flags |= DeleteMarked; } 48 776060 : void ClearDelete() { flags &= ~DeleteMarked; } 49 15706853 : bool IsDeleted() const { return (flags & DeleteMarked) != 0; } 50 : 51 2555507 : void set_onlist() { flags |= Onlist; } 52 2552387 : void clear_onlist() { flags &= ~Onlist; } 53 6425853 : bool is_onlist() { return (flags & Onlist); } 54 : 55 524743 : void SetOnRemoveQ() { 56 524743 : onremoveq_.exchange(true); 57 524923 : } 58 1048775 : bool IsOnRemoveQ() { return (onremoveq_); } 59 37 : void ClearOnRemoveQ() { 60 37 : onremoveq_.exchange(false); 61 38 : } 62 : 63 : //member hook in change list 64 : boost::intrusive::list_member_hook<> chg_list_; 65 : 66 : void set_last_change_at(uint64_t time); 67 : void set_last_change_at_to_now(); 68 6343 : const uint64_t last_change_at() const { return last_change_at_; } 69 : const std::string last_change_at_str() const; 70 : void set_last_update_at(uint64_t time); 71 : void set_last_update_at_to_now(); 72 2009794 : const uint64_t last_update_at() const { return last_update_at_; } 73 : DBTablePartBase *get_table_partition() const; 74 : void set_table_partition(DBTablePartBase *tpart); 75 : DBTableBase *get_table() const; 76 : void Notify(); 77 : 78 : private: 79 : enum DbEntryFlags { 80 : Onlist = 1 << 0, 81 : DeleteMarked = 1 << 1, 82 : }; 83 : typedef std::map<ListenerId, DBState *> StateMap; 84 : DBTablePartBase *tpart_; 85 : StateMap state_; 86 : uint8_t flags; 87 : std::atomic<bool> onremoveq_; 88 : uint64_t last_change_at_; // time at which entry was last 'changed' 89 : uint64_t last_update_at_; // time at which entry was last 'updated' 90 : DISALLOW_COPY_AND_ASSIGN(DBEntryBase); 91 : }; 92 : 93 : // An implementation of DBEntryBase that uses boost::set as data-store 94 : // Most of the DB Table implementations should derive from here instead of 95 : // DBEntryBase directly. 96 : // Derive directly from DBEntryBase only if there is a strong reason to do so 97 : class DBEntry : public DBEntryBase { 98 : public: 99 4767897 : DBEntry() { }; 100 4767465 : virtual ~DBEntry() { }; 101 : 102 : // Set key fields in the DBEntry 103 : virtual void SetKey(const DBRequestKey *key) = 0; 104 : 105 : // Comparator used in Tree management 106 : virtual bool IsLess(const DBEntry &rhs) const = 0; 107 : 108 31521606 : bool operator<(const DBEntry &rhs) const { 109 31521606 : return IsLess(rhs); 110 : } 111 : 112 : private: 113 : friend class DBTablePartition; 114 : boost::intrusive::set_member_hook<> node_; 115 : DISALLOW_COPY_AND_ASSIGN(DBEntry); 116 : }; 117 : 118 : #endif