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