1 /* 2 * Copyright (C) 2009 Codership Oy <info@codership.com> 3 */ 4 5 6 /*! 7 * @file Group view class (used in the ProtoUpMeta (protolay.hpp) 8 */ 9 10 #ifndef _GCOMM_VIEW_HPP_ 11 #define _GCOMM_VIEW_HPP_ 12 13 14 #include "gcomm/uuid.hpp" 15 #include "gcomm/types.hpp" 16 #include "gcomm/map.hpp" 17 #include "gcomm/conf.hpp" 18 19 namespace gcomm 20 { 21 typedef enum 22 { 23 V_NONE = -1, 24 V_REG = 0, 25 V_TRANS = 1, 26 V_NON_PRIM = 2, 27 V_PRIM = 3 28 } ViewType; 29 30 class ViewId 31 { 32 public: 33 34 ViewId(const ViewType type=V_NONE,const UUID & uuid=UUID::nil (),const uint32_t seq=0)35 ViewId(const ViewType type = V_NONE, 36 const UUID& uuid = UUID::nil(), 37 const uint32_t seq = 0) : 38 type_(type), 39 uuid_(uuid), 40 seq_ (seq) 41 { } 42 ViewId(const ViewType type,const ViewId & vi)43 ViewId(const ViewType type, 44 const ViewId& vi) : 45 type_(type), 46 uuid_(vi.uuid()), 47 seq_ (vi.seq()) 48 { } 49 ~ViewId()50 virtual ~ViewId() { } 51 type() const52 ViewType type() const { return type_; } 53 uuid() const54 const UUID& uuid() const { return uuid_; } 55 seq() const56 uint32_t seq() const { return seq_; } 57 58 size_t unserialize(const gu::byte_t* buf, size_t buflen, size_t offset); 59 60 size_t serialize(gu::byte_t* buf, size_t buflen, size_t offset) const; 61 serial_size()62 static size_t serial_size() 63 { 64 return UUID::serial_size() + sizeof(reinterpret_cast<ViewId*>(0)->seq_); 65 } 66 operator <(const ViewId & cmp) const67 bool operator<(const ViewId& cmp) const 68 { 69 // View ordering: 70 // 1) view seq less than 71 // 2) uuid newer than 72 // 3) type less than 73 return (seq_ < cmp.seq_ || 74 (seq_ == cmp.seq_ && 75 (cmp.uuid_.older(uuid_) || 76 (uuid_ == cmp.uuid_ && type_ < cmp.type_) ) ) ); 77 } 78 operator ==(const ViewId & cmp) const79 bool operator==(const ViewId& cmp) const 80 { 81 return (seq_ == cmp.seq_ && 82 type_ == cmp.type_ && 83 uuid_ == cmp.uuid_); 84 } 85 operator !=(const ViewId & cmp) const86 bool operator!=(const ViewId& cmp) const 87 { 88 return !(*this == cmp); 89 } 90 write_stream(std::ostream & os) const91 std::ostream& write_stream(std::ostream& os) const { 92 os << static_cast<int>(type_) << " "; 93 uuid_.write_stream(os); 94 os << " " << seq_; 95 return os; 96 } read_stream(std::istream & is)97 std::istream& read_stream(std::istream& is) { 98 int t; 99 is >> t; 100 type_ = static_cast<ViewType>(t); 101 uuid_.read_stream(is); 102 is >> seq_; 103 return is; 104 } 105 106 private: 107 ViewType type_; 108 UUID uuid_; // uniquely identifies the sequence of group views (?) 109 uint32_t seq_; // position in the sequence (?) 110 }; 111 112 std::ostream& operator<<(std::ostream&, const ViewId&); 113 114 typedef uint8_t SegmentId; 115 116 class Node 117 { 118 public: Node(SegmentId segment=0)119 Node(SegmentId segment = 0) : segment_(segment) 120 { } segment() const121 SegmentId segment() const { return segment_; } operator ==(const Node & cmp) const122 bool operator==(const Node& cmp) const { return true; } operator <(const Node & cmp) const123 bool operator<(const Node& cmp) const { return true; } write_stream(std::ostream & os) const124 std::ostream& write_stream(std::ostream& os) const 125 { 126 os << static_cast<int>(segment_); 127 return os; 128 } read_stream(std::istream & is)129 std::istream& read_stream(std::istream& is) 130 { 131 int seg; 132 is >> seg; 133 segment_ = static_cast<SegmentId>(seg); 134 return is; 135 } 136 private: 137 SegmentId segment_; 138 }; 139 operator <<(std::ostream & os,const Node & n)140 inline std::ostream& operator<<(std::ostream& os, const Node& n) 141 { 142 return (os << static_cast<int>(n.segment()) ); 143 } 144 145 146 class NodeList : public gcomm::Map<UUID, Node> { }; 147 148 class View 149 { 150 public: 151 View()152 View() : 153 version_ (-1), 154 bootstrap_ (false), 155 view_id_ (V_NONE), 156 members_ (), 157 joined_ (), 158 left_ (), 159 partitioned_ () 160 { } 161 View(int version,const ViewId & view_id,bool bootstrap=false)162 View(int version, const ViewId& view_id, bool bootstrap = false) : 163 version_ (version), 164 bootstrap_ (bootstrap), 165 view_id_ (view_id), 166 members_ (), 167 joined_ (), 168 left_ (), 169 partitioned_ () 170 { } 171 ~View()172 ~View() {} 173 version() const174 int version() const { return version_; } 175 176 void add_member (const UUID& pid, SegmentId segment); 177 178 void add_members (NodeList::const_iterator begin, 179 NodeList::const_iterator end); 180 181 void add_joined (const UUID& pid, SegmentId segment); 182 void add_left (const UUID& pid, SegmentId segment); 183 void add_partitioned (const UUID& pid, SegmentId segment); 184 185 const NodeList& members () const; 186 const NodeList& joined () const; 187 const NodeList& left () const; 188 const NodeList& partitioned () const; 189 members()190 NodeList& members() { return members_; } 191 is_member(const UUID & uuid) const192 bool is_member(const UUID& uuid) const 193 { return members_.find(uuid) != members_.end(); } 194 is_joining(const UUID & uuid) const195 bool is_joining(const UUID& uuid) const 196 { return joined_.find(uuid) != joined_.end(); } 197 is_leaving(const UUID & uuid) const198 bool is_leaving(const UUID& uuid) const 199 { return left_.find(uuid) != left_.end(); } 200 is_partitioning(const UUID & uuid) const201 bool is_partitioning(const UUID& uuid) const 202 { return partitioned_.find(uuid) != partitioned_.end(); } 203 204 205 ViewType type () const; 206 const ViewId& id () const; 207 const UUID& representative () const; 208 209 bool is_empty() const; is_bootstrap() const210 bool is_bootstrap() const { return bootstrap_; } 211 212 std::ostream& write_stream(std::ostream& os) const; 213 std::istream& read_stream(std::istream& is); 214 private: 215 int version_; // view protocol version, derived from evs group 216 bool bootstrap_; // Flag indicating if view was bootstrapped 217 ViewId view_id_; // View identifier 218 NodeList members_; // List of members in view 219 NodeList joined_; // List of newly joined members in view 220 NodeList left_; // Fracefully left members from previous view 221 NodeList partitioned_; // Partitioned members from previous view 222 }; 223 224 bool operator==(const gcomm::View&, const gcomm::View&); 225 std::ostream& operator<<(std::ostream&, const View&); 226 227 class ViewState 228 { 229 public: ViewState(UUID & my_uuid,View & view,gu::Config & conf)230 ViewState(UUID& my_uuid, View& view, gu::Config& conf): 231 my_uuid_(my_uuid), 232 view_(view), 233 file_name_(get_viewstate_file_name(conf)) 234 { } 235 std::ostream& write_stream(std::ostream& os) const; 236 std::istream& read_stream(std::istream& is); 237 void write_file() const; 238 bool read_file(); 239 static void remove_file(gu::Config& conf); operator ==(const ViewState & vst) const240 bool operator== (const ViewState& vst) const 241 { 242 return my_uuid_ == vst.my_uuid_ && 243 view_ == vst.view_; 244 } 245 private: 246 UUID& my_uuid_; 247 View& view_; 248 std::string file_name_; 249 250 static std::string get_viewstate_file_name(gu::Config& conf); 251 }; 252 } // namespace gcomm 253 254 #endif // _GCOMM_VIEW_HPP_ 255