MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / getPriorityFunc

Method getPriorityFunc

src/Common/GetPriorityForLoadBalancing.cpp:13–84  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

11}
12
13GetPriorityForLoadBalancing::Func
14GetPriorityForLoadBalancing::getPriorityFunc(LoadBalancing load_balance, size_t offset, size_t pool_size) const
15{
16 std::function<Priority(size_t index)> get_priority;
17 switch (load_balance)
18 {
19 case LoadBalancing::NEAREST_HOSTNAME:
20 if (hostname_prefix_distance.empty())
21 throw Exception(ErrorCodes::LOGICAL_ERROR, "It's a bug: hostname_prefix_distance is not initialized");
22 get_priority = [this](size_t i) { return Priority{static_cast<Int64>(hostname_prefix_distance[i])}; };
23 break;
24 case LoadBalancing::HOSTNAME_LEVENSHTEIN_DISTANCE:
25 if (hostname_levenshtein_distance.empty())
26 throw Exception(ErrorCodes::LOGICAL_ERROR, "It's a bug: hostname_levenshtein_distance is not initialized");
27 get_priority = [this](size_t i) { return Priority{static_cast<Int64>(hostname_levenshtein_distance[i])}; };
28 break;
29 case LoadBalancing::HOSTNAME_LONGEST_COMMON_PREFIX:
30 if (hostname_longest_common_prefix.empty())
31 throw Exception(ErrorCodes::LOGICAL_ERROR, "It's a bug: hostname_longest_common_prefix is not initialized");
32 /// `Priority` is "lower value means higher priority", and the other hostname strategies store a
33 /// *distance* (smaller == more similar == preferred) that is returned verbatim. Here we instead
34 /// store a *similarity* (the common prefix length, where larger == more similar == preferred), so
35 /// we negate it to turn it into a priority. We deliberately do not store a synthetic distance such
36 /// as `BIG - length`: negating here keeps the stored vector semantically honest (it really is the
37 /// common prefix length) and avoids an arbitrary magic constant.
38 get_priority = [this](size_t i) { return Priority{-static_cast<Int64>(hostname_longest_common_prefix[i])}; };
39 break;
40 case LoadBalancing::HOSTNAME_LONGEST_COMMON_SUFFIX:
41 if (hostname_longest_common_suffix.empty())
42 throw Exception(ErrorCodes::LOGICAL_ERROR, "It's a bug: hostname_longest_common_suffix is not initialized");
43 /// See the comment for HOSTNAME_LONGEST_COMMON_PREFIX: the stored value is a similarity (common
44 /// suffix length, larger == preferred), so we negate it to obtain a priority (lower == preferred).
45 get_priority = [this](size_t i) { return Priority{-static_cast<Int64>(hostname_longest_common_suffix[i])}; };
46 break;
47 case LoadBalancing::IN_ORDER:
48 get_priority = [](size_t i) { return Priority{static_cast<Int64>(i)}; };
49 break;
50 case LoadBalancing::RANDOM:
51 break;
52 case LoadBalancing::FIRST_OR_RANDOM:
53 get_priority = [offset](size_t i) { return i != offset ? Priority{1} : Priority{0}; };
54 break;
55 case LoadBalancing::ROUND_ROBIN:
56 /// `last_used` is `std::atomic<size_t>`. Use relaxed ordering: this counter
57 /// is only used to derive a rotation index, and there is no happens-before
58 /// relationship that needs to be observed by other threads. We compute
59 /// `local_last_used` from the pre-increment value so that two concurrent
60 /// callers receive distinct rotations of the round-robin sequence.
61 auto local_last_used = last_used.fetch_add(1, std::memory_order_relaxed) % pool_size;
62
63 // Example: pool_size = 5
64 // | local_last_used | i=0 | i=1 | i=2 | i=3 | i=4 |
65 // | 0 | 4 | 0 | 1 | 2 | 3 |
66 // | 1 | 3 | 4 | 0 | 1 | 2 |
67 // | 2 | 2 | 3 | 4 | 0 | 1 |
68 // | 3 | 1 | 2 | 3 | 4 | 0 |
69 // | 4 | 0 | 1 | 2 | 3 | 4 |
70

Callers 6

TESTFunction · 0.80
preferredReplicaFunction · 0.80
shuffleHostsMethod · 0.80
addPipeMethod · 0.80
getMethod · 0.80
makeGetPriorityFuncMethod · 0.80

Calls 2

ExceptionClass · 0.70
emptyMethod · 0.45

Tested by 2

TESTFunction · 0.64
preferredReplicaFunction · 0.64