Hazelcast C++ Client
Hazelcast C++ Client Library
Loading...
Searching...
No Matches
cluster.cpp
1/*
2 * Copyright (c) 2008-2025, Hazelcast, Inc. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <functional>
18#include <boost/uuid/uuid_io.hpp>
19#include <boost/functional/hash.hpp>
20
21#include "hazelcast/client/cluster.h"
22#include "hazelcast/client/spi/impl/ClientClusterServiceImpl.h"
23#include "hazelcast/client/membership_listener.h"
24#include "hazelcast/client/initial_membership_event.h"
25#include "hazelcast/client/member.h"
26#include "hazelcast/client/serialization/serialization.h"
27#include "hazelcast/client/membership_event.h"
28#include "hazelcast/client/impl/vector_clock.h"
29#include "hazelcast/client/member_selectors.h"
30#include "hazelcast/client/internal/partition/strategy/StringPartitioningStrategy.h"
31
32namespace hazelcast {
33namespace client {
34cluster::cluster(spi::impl::ClientClusterServiceImpl& cluster_service)
35 : cluster_service_(cluster_service)
36{}
37
38std::vector<member>
40{
41 return cluster_service_.get_member_list();
42}
43
44boost::uuids::uuid
46{
47 return cluster_service_.add_membership_listener(std::move(listener));
48}
49
50bool
51cluster::remove_membership_listener(boost::uuids::uuid registration_id)
52{
53 return cluster_service_.remove_membership_listener(registration_id);
54}
55
56member::member()
57 : lite_member_(false)
58 , version_{ 0, 0, 0 }
59{}
60
61member::member(address member_address,
62 boost::uuids::uuid uuid,
63 bool lite,
64 std::unordered_map<std::string, std::string> attr,
65 std::unordered_map<endpoint_qualifier, address> address_map,
66 version v)
67 : address_(std::move(member_address))
68 , uuid_(uuid)
69 , lite_member_(lite)
70 , attributes_(std::move(attr))
71 , address_map_(std::move(address_map))
72 , version_(v)
73{}
74
75member::member(address member_address)
76 : address_(member_address)
77 , lite_member_(false)
78 , version_{ 0, 0, 0 }
79{}
80
81member::member(boost::uuids::uuid uuid)
82 : uuid_(uuid)
83 , lite_member_(false)
84 , version_{ 0, 0, 0 }
85{}
86
87const address&
89{
90 return address_;
91}
92
93boost::uuids::uuid
95{
96 return uuid_;
97}
98
99bool
101{
102 return lite_member_;
103}
104
105const std::unordered_map<std::string, std::string>&
106member::get_attributes() const
107{
108 return attributes_;
109}
110
111std::ostream&
112operator<<(std::ostream& out, const member& member)
113{
114 const address& address = member.get_address();
115 out << "Member[";
116 out << address.get_host();
117 out << "]";
118 out << ":";
119 out << address.get_port();
120 out << " - " << boost::uuids::to_string(member.get_uuid());
121 if (member.is_lite_member()) {
122 out << " lite";
123 }
124 return out;
125}
126
127const std::string*
128member::get_attribute(const std::string& key) const
129{
130 std::unordered_map<std::string, std::string>::const_iterator it =
131 attributes_.find(key);
132 if (attributes_.end() != it) {
133 return &(it->second);
134 } else {
135 return NULL;
136 }
137}
138
141{
142 return version_;
143}
144
145bool
146member::lookup_attribute(const std::string& key) const
147{
148 return attributes_.find(key) != attributes_.end();
149}
150
151bool
152member::operator<(const member& rhs) const
153{
154 return uuid_ < rhs.uuid_;
155}
156
157const std::unordered_map<endpoint_qualifier, address>&
158member::address_map() const
159{
160 return address_map_;
161}
162
163bool
164operator==(const member& lhs, const member& rhs)
165{
166 return lhs.address_ == rhs.address_ && lhs.uuid_ == rhs.uuid_;
167}
168
169endpoint::endpoint(boost::uuids::uuid uuid,
170 boost::optional<address> socket_address)
171 : uuid_(uuid)
172 , socket_address_(std::move(socket_address))
173{}
174
175boost::uuids::uuid
177{
178 return uuid_;
179}
180
181const boost::optional<address>&
183{
184 return socket_address_;
185}
186
189 const member& m,
190 membership_event_type event_type,
191 const std::unordered_map<boost::uuids::uuid,
192 member,
193 boost::hash<boost::uuids::uuid>>& members_list)
194 : cluster_(cluster)
195 , member_(m)
196 , event_type_(event_type)
197 , members_(members_list)
198{}
199
201
202std::unordered_map<boost::uuids::uuid, member, boost::hash<boost::uuids::uuid>>
204{
205 return members_;
206}
207
208cluster&
210{
211 return cluster_;
212}
213
214membership_event::membership_event_type
216{
217 return event_type_;
218}
219
220const member&
222{
223 return member_;
224}
225
226local_endpoint::local_endpoint(boost::uuids::uuid uuid,
227 boost::optional<address> socket_address,
228 std::string name,
229 std::unordered_set<std::string> labels)
230 : endpoint(uuid, std::move(socket_address))
231 , name_(std::move(name))
232 , labels_(std::move(labels))
233{}
234
235const std::string&
236local_endpoint::get_name() const
237{
238 return name_;
239}
240
241namespace impl {
242vector_clock::vector_clock() = default;
243
244vector_clock::vector_clock(
245 const vector_clock::timestamp_vector& replica_logical_timestamps)
246 : replica_timestamp_entries_(replica_logical_timestamps)
247{
248 for (const vector_clock::timestamp_vector::value_type& replicaTimestamp :
249 replica_logical_timestamps) {
250 replica_timestamps_[replicaTimestamp.first] = replicaTimestamp.second;
251 }
252}
253
254vector_clock::timestamp_vector
255vector_clock::entry_set()
256{
257 return replica_timestamp_entries_;
258}
259
260bool
261vector_clock::is_after(vector_clock& other)
262{
263 bool anyTimestampGreater = false;
264 for (const vector_clock::timestamp_map::value_type& otherEntry :
265 other.replica_timestamps_) {
266 const auto& replicaId = otherEntry.first;
267 int64_t otherReplicaTimestamp = otherEntry.second;
268 std::pair<bool, int64_t> localReplicaTimestamp =
269 get_timestamp_for_replica(replicaId);
270
271 if (!localReplicaTimestamp.first ||
272 localReplicaTimestamp.second < otherReplicaTimestamp) {
273 return false;
274 } else if (localReplicaTimestamp.second > otherReplicaTimestamp) {
275 anyTimestampGreater = true;
276 }
277 }
278 // there is at least one local timestamp greater or local vector clock has
279 // additional timestamps
280 return anyTimestampGreater ||
281 other.replica_timestamps_.size() < replica_timestamps_.size();
282}
283
284std::pair<bool, int64_t>
285vector_clock::get_timestamp_for_replica(boost::uuids::uuid replica_id)
286{
287 if (replica_timestamps_.count(replica_id) == 0) {
288 return std::make_pair(false, -1);
289 }
290 return std::make_pair(true, replica_timestamps_[replica_id]);
291}
292} // namespace impl
293
294bool
295member_selectors::data_member_selector::select(const member& member) const
296{
297 return !member.is_lite_member();
298}
299
300const std::unique_ptr<member_selector> member_selectors::DATA_MEMBER_SELECTOR(
301 new member_selectors::data_member_selector());
302
303namespace internal {
304namespace partition {
305namespace strategy {
306std::string
307StringPartitioningStrategy::get_base_name(const std::string& name)
308{
309 size_t index_of = name.find('@');
310 if (index_of == std::string::npos) {
311 return name;
312 }
313 return name.substr(0, index_of);
314}
315
316std::string
317StringPartitioningStrategy::get_partition_key(const std::string& key)
318{
319 size_t firstIndexOf = key.find('@');
320 if (firstIndexOf == std::string::npos) {
321 return key;
322 } else {
323 return key.substr(firstIndexOf + 1);
324 }
325}
326} // namespace strategy
327} // namespace partition
328} // namespace internal
329
330bool
331operator==(const endpoint_qualifier& lhs, const endpoint_qualifier& rhs)
332{
333 return lhs.type == rhs.type && lhs.identifier == rhs.identifier;
334}
335
336bool
337member::version::operator==(const member::version& rhs) const
338{
339 return major == rhs.major && minor == rhs.minor && patch == rhs.patch;
340}
341
342bool
343member::version::operator!=(const member::version& rhs) const
344{
345 return !(rhs == *this);
346}
347
348bool
349member::version::operator<(const member::version& rhs) const
350{
351 if (major < rhs.major)
352 return true;
353 if (rhs.major < major)
354 return false;
355 if (minor < rhs.minor)
356 return true;
357 if (rhs.minor < minor)
358 return false;
359 return patch < rhs.patch;
360}
361
362bool
363member::version::operator>(const member::version& rhs) const
364{
365 return rhs < *this;
366}
367
368bool
369member::version::operator<=(const member::version& rhs) const
370{
371 return !(rhs < *this);
372}
373
374bool
375member::version::operator>=(const member::version& rhs) const
376{
377 return !(*this < rhs);
378}
379
380std::ostream&
381operator<<(std::ostream& os, const member::version& version)
382{
383 os << version.major << "." << version.minor << "." << version.patch;
384 return os;
385}
386} // namespace client
387} // namespace hazelcast
388
389namespace std {
390std::size_t
391hash<hazelcast::client::member>::operator()(
392 const hazelcast::client::member& m) const noexcept
393{
394 std::size_t seed = 0;
395 boost::hash_combine(
396 seed, std::hash<hazelcast::client::address>()(m.get_address()));
397 boost::hash_combine(seed, m.get_uuid());
398 return seed;
399}
400
401std::size_t
402hash<hazelcast::client::endpoint_qualifier>::operator()(
403 const hazelcast::client::endpoint_qualifier& e) const noexcept
404{
405 std::size_t seed = 0;
406 boost::hash_combine(seed, e.type);
407 boost::hash_combine(seed, e.identifier);
408 return seed;
409}
410} // namespace std
Represents an address of a client or member in the cluster.
Definition address.h:37
Hazelcast cluster interface.
Definition cluster.h:37
cluster(spi::impl::ClientClusterServiceImpl &cluster_service)
Constructor.
Definition cluster.cpp:34
std::vector< member > get_members()
Set of current members of the cluster.
Definition cluster.cpp:39
bool remove_membership_listener(boost::uuids::uuid registration_id)
Removes the specified membership_listener.
Definition cluster.cpp:51
boost::uuids::uuid add_membership_listener(membership_listener &&listener)
Adds membership_listener to listen for membership updates.
Definition cluster.cpp:45
Endpoint represents a peer in the cluster.
Definition endpoint.h:35
boost::uuids::uuid get_uuid() const
Returns the UUID of this endpoint.
Definition cluster.cpp:176
const boost::optional< address > & get_socket_address() const
Returns the socket address for this endpoint.
Definition cluster.cpp:182
hz_cluster member class.
Definition member.h:62
bool is_lite_member() const
Lite member is does not hold data.
Definition cluster.cpp:100
boost::uuids::uuid get_uuid() const
Returns UUID of this member.
Definition cluster.cpp:94
bool lookup_attribute(const std::string &key) const
check if an attribute is defined for given key.
Definition cluster.cpp:146
const std::string * get_attribute(const std::string &key) const
Returns the value of the specified key for this member or default constructed value if value is undef...
Definition cluster.cpp:128
version get_version() const
Returns the Hazelcast codebase version of this member; this may or may not be different from the vers...
Definition cluster.cpp:140
const address & get_address() const
Returns the socket address of this member.
Definition cluster.cpp:88
std::unordered_map< boost::uuids::uuid, member, boost::hash< boost::uuids::uuid > > get_members() const
Returns a consistent view of the the members exactly after this MembershipEvent has been processed.
Definition cluster.cpp:203
cluster & get_cluster()
Returns the cluster of the event.
Definition cluster.cpp:209
virtual ~membership_event()
Destructor.
membership_event_type get_event_type() const
Returns the membership event type; MembershipEvent::MEMBER_JOINED , MembershipEvent::MEMBER_LEFT.
Definition cluster.cpp:215
const member & get_member() const
Returns the removed or added member.
Definition cluster.cpp:221
membership_event(cluster &cluster, const member &m, membership_event_type event_type, const std::unordered_map< boost::uuids::uuid, member, boost::hash< boost::uuids::uuid > > &members_list)
Internal API.
Definition cluster.cpp:187
STL namespace.