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 __DB_IFMAP_UPDATE_H__ 7 : #define __DB_IFMAP_UPDATE_H__ 8 : 9 : #include <boost/crc.hpp> // for boost::crc_32_type 10 : #include <boost/intrusive/list.hpp> 11 : #include <boost/intrusive/slist.hpp> 12 : 13 : #include "base/bitset.h" 14 : #include "base/dependency.h" 15 : #include "db/db_entry.h" 16 : #include "ifmap/ifmap_link.h" 17 : 18 : struct IFMapObjectPtr { 19 : enum ObjectType { 20 : NIL, 21 : NODE, 22 : LINK 23 : }; 24 : 25 : IFMapObjectPtr(); 26 : explicit IFMapObjectPtr(IFMapNode *node); 27 : explicit IFMapObjectPtr(IFMapLink *link); 28 : 29 : void set(IFMapNode *node) { 30 : type = NODE; 31 : u.node = node; 32 : } 33 : void set(IFMapLink *link) { 34 : type = LINK; 35 : u.link = link; 36 : } 37 1070 : bool IsNode() const { return ((type == NODE) ? true : false); } 38 458 : bool IsLink() const { return ((type == LINK) ? true : false); } 39 : ObjectType type; 40 : union { 41 : void *ptr; 42 : IFMapNode *node; 43 : IFMapLink *link; 44 : } u; 45 : }; 46 : 47 : struct IFMapListEntry { 48 : enum EntryType { 49 : UPDATE, // add or change operation 50 : DEL, // delete 51 : MARKER 52 : }; 53 1431 : IFMapListEntry(EntryType type) : 54 1431 : type(type), queue_insert_at(0), sequence(0) { } 55 1431 : virtual ~IFMapListEntry() { } 56 : 57 : boost::intrusive::list_member_hook<> node; 58 : EntryType type; 59 : uint64_t queue_insert_at; 60 : uint64_t sequence; 61 : 62 0 : virtual std::string ToString() { 63 0 : return std::string("To implement"); 64 : } 65 1832 : bool IsMarker() const { return ((type == MARKER) ? true : false); } 66 3140 : bool IsUpdate() const { return ((type == UPDATE) ? true : false); } 67 2248 : bool IsDelete() const { return ((type == DEL) ? true : false); } 68 890 : std::string TypeToString() { 69 890 : if (IsMarker()) { 70 0 : return "Marker"; 71 890 : } else if (IsUpdate()) { 72 890 : return "Update"; 73 0 : } else if (IsDelete()) { 74 0 : return "Delete"; 75 : } else { 76 0 : return "Unknown"; 77 : } 78 : } 79 : void set_queue_insert_at_to_now(); 80 : // Return how much time ago the entry was inserted. 81 : std::string queue_insert_ago_str(); 82 3158 : void set_sequence(uint64_t seq) { sequence = seq; } 83 184 : uint64_t get_sequence() { return sequence; } 84 : }; 85 : 86 : class IFMapUpdate : public IFMapListEntry { 87 : public: 88 : IFMapUpdate(IFMapNode *node, bool positive); 89 : IFMapUpdate(IFMapLink *link, bool positive); 90 2428 : virtual ~IFMapUpdate() { } 91 : 92 : void AdvertiseReset(const BitSet &set); 93 : void AdvertiseOr(const BitSet &set); 94 : void SetAdvertise(const BitSet &set); 95 6030 : const BitSet &advertise() const { return advertise_; } 96 : 97 7320 : const IFMapObjectPtr &data() const { return data_; } 98 : std::string ConfigName(); 99 : virtual std::string ToString(); 100 892 : bool IsNode() const { return data_.IsNode(); } 101 458 : bool IsLink() const { return data_.IsLink(); } 102 : 103 : private: 104 : friend class IFMapState; 105 : boost::intrusive::slist_member_hook<> node_; 106 : IFMapObjectPtr data_; 107 : BitSet advertise_; 108 : }; 109 : 110 : struct IFMapMarker : public IFMapListEntry { 111 : IFMapMarker(); 112 231 : virtual ~IFMapMarker() { } 113 : virtual std::string ToString(); 114 : BitSet mask; 115 : }; 116 : 117 : // State associated with each DB entry. 118 : class IFMapState : public DBState { 119 : public: 120 : typedef boost::crc_32_type::value_type crc32type; 121 : typedef boost::intrusive::member_hook< 122 : IFMapUpdate, boost::intrusive::slist_member_hook<>, &IFMapUpdate::node_ 123 : > MemberHook; 124 : typedef boost::intrusive::slist<IFMapUpdate, MemberHook> UpdateList; 125 : 126 : IFMapState(IFMapNode *node); 127 : IFMapState(IFMapLink *link); 128 : virtual ~IFMapState(); 129 : 130 43547 : const BitSet &interest() const { return interest_; } 131 15482 : const BitSet &advertised() const { return advertised_; } 132 : 133 262 : const UpdateList &update_list() const { return update_list_; } 134 : IFMapUpdate *GetUpdate(IFMapListEntry::EntryType type); 135 : void Insert(IFMapUpdate *update); 136 : void Remove(IFMapUpdate *update); 137 : 138 462 : void InterestOr(const BitSet &bset) { interest_ |= bset; } 139 3567 : void SetInterest(const BitSet &bset) { interest_ = bset; } 140 147 : void InterestReset(const BitSet &set) { interest_.Reset(set); } 141 : 142 1032 : void AdvertisedOr(const BitSet &set) { advertised_ |= set; } 143 184 : void AdvertisedReset(const BitSet &set) { advertised_.Reset(set); } 144 : 145 : template <typename Disposer> 146 5077 : void ClearAndDispose(Disposer disposer) { 147 5077 : update_list_.clear_and_dispose(disposer); 148 5077 : } 149 : 150 2757 : virtual void SetValid() { sig_ = 0; } 151 110 : virtual void ClearValid() { sig_ = kInvalidSig; } 152 680 : virtual bool IsValid() const { return sig_ != kInvalidSig; } 153 157 : virtual bool IsInvalid() const { return sig_ == kInvalidSig; } 154 3592 : const crc32type &crc() const { return crc_; } 155 2249 : void SetCrc(crc32type &crc) { crc_ = crc; } 156 : virtual bool CanDelete() = 0; 157 : const IFMapObjectPtr &data() const { return data_; } 158 : IFMapNode *GetIFMapNode() const; 159 : IFMapLink *GetIFMapLink() const; 160 110 : bool IsNode() const { return data_.IsNode(); } 161 : bool IsLink() const { return data_.IsLink(); } 162 : 163 : protected: 164 : static const uint32_t kInvalidSig = -1; 165 : uint32_t sig_; 166 : IFMapObjectPtr data_; 167 : 168 : private: 169 : // The set of clients known to be interested in this update. 170 : BitSet interest_; 171 : // The set of clients to which this update has been advertised. 172 : BitSet advertised_; 173 : UpdateList update_list_; 174 : crc32type crc_; 175 : }; 176 : 177 : class IFMapNodeState : public IFMapState { 178 : public: 179 : typedef DependencyList<IFMapLink, IFMapNodeState>::iterator iterator; 180 : typedef DependencyList<IFMapLink, IFMapNodeState>::const_iterator 181 : const_iterator; 182 : explicit IFMapNodeState(IFMapNode *node); 183 : 184 0 : void SetValid() { IFMapState::SetValid(); } 185 3537 : void SetValid(const IFMapNode *node) { sig_ = 0; } 186 : bool HasDependents() const; 187 : 188 214 : iterator begin() { return dependents_.begin(); } 189 560 : iterator end() { return dependents_.end(); } 190 : 191 : const_iterator begin() const { return dependents_.begin(); } 192 : const_iterator end() const { return dependents_.end(); } 193 : 194 160 : const BitSet &nmask() const { return nmask_; } 195 68 : void nmask_clear() { nmask_.clear(); } 196 12 : void nmask_set(int bit) { nmask_.set(bit); } 197 78 : virtual bool CanDelete() { 198 78 : return (update_list().empty() && IsInvalid() && !HasDependents()); 199 : } 200 : 201 : private: 202 11028 : DEPENDENCY_LIST(IFMapLink, IFMapNodeState, dependents_); 203 : BitSet nmask_; // new bitmask computed by graph traversal 204 : }; 205 : 206 : class IFMapLinkState : public IFMapState { 207 : public: 208 : explicit IFMapLinkState(IFMapLink *link); 209 : void SetDependency(IFMapNodeState *first, IFMapNodeState *second); 210 : void RemoveDependency(); 211 : bool HasDependency() const; 212 : 213 2757 : void SetValid() { IFMapState::SetValid(); } 214 : void SetValid(const IFMapLink *link) { sig_ = 0; } 215 : 216 672 : IFMapNodeState *left() { return left_.get(); } 217 672 : IFMapNodeState *right() { return right_.get(); } 218 75 : virtual bool CanDelete() { 219 75 : return (update_list().empty() && IsInvalid()); 220 : } 221 : 222 : private: 223 : DependencyRef<IFMapLink, IFMapNodeState> left_; 224 : DependencyRef<IFMapLink, IFMapNodeState> right_; 225 : }; 226 : 227 : #endif