/root/doris/be/src/util/uid_util.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | #pragma once |
19 | | |
20 | | #include <gen_cpp/Types_types.h> |
21 | | #include <gen_cpp/types.pb.h> |
22 | | #include <stdint.h> |
23 | | |
24 | | #include <boost/random/mersenne_twister.hpp> |
25 | | #include <boost/uuid/random_generator.hpp> |
26 | | #include <boost/uuid/uuid.hpp> |
27 | | #include <boost/uuid/uuid_io.hpp> |
28 | | #include <cstring> |
29 | | #include <ostream> |
30 | | #include <string> |
31 | | #include <string_view> |
32 | | |
33 | | #include "util/uuid_generator.h" |
34 | | |
35 | | namespace doris { |
36 | | |
37 | | // convert int to a hex format string, buf must enough to hold converted hex string |
38 | | template <typename T> |
39 | 27.2k | void to_hex(T val, char* buf) { |
40 | 27.2k | static const char* digits = "0123456789abcdef"; |
41 | 463k | for (int i = 0; i < 2 * sizeof(T); ++i) { |
42 | 436k | buf[2 * sizeof(T) - 1 - i] = digits[val & 0x0F]; |
43 | 436k | val >>= 4; |
44 | 436k | } |
45 | 27.2k | } |
46 | | |
47 | | template <typename T> |
48 | 2.50k | void from_hex(T* ret, std::string_view buf) { |
49 | 2.50k | T val = 0; |
50 | 40.0k | for (char i : buf) { |
51 | 40.0k | int buf_val = 0; |
52 | 40.0k | if (i >= '0' && i <= '9') { |
53 | 35.1k | buf_val = i - '0'; |
54 | 35.1k | } else { |
55 | 4.89k | buf_val = i - 'a' + 10; |
56 | 4.89k | } |
57 | 40.0k | val <<= 4; |
58 | 40.0k | val = val | buf_val; |
59 | 40.0k | } |
60 | 2.50k | *ret = val; |
61 | 2.50k | } |
62 | | |
63 | | struct UniqueId { |
64 | | int64_t hi = 0; |
65 | | int64_t lo = 0; |
66 | | |
67 | 12.4k | UniqueId() = default; |
68 | 13.8k | UniqueId(int64_t hi_, int64_t lo_) : hi(hi_), lo(lo_) {} |
69 | 3.73k | UniqueId(const UniqueId& uid) : hi(uid.hi), lo(uid.lo) {} |
70 | 26 | UniqueId(const TUniqueId& tuid) : hi(tuid.hi), lo(tuid.lo) {} |
71 | 547 | UniqueId(const PUniqueId& puid) : hi(puid.hi()), lo(puid.lo()) {} |
72 | 6 | UniqueId(const std::string& hi_str, const std::string& lo_str) { |
73 | 6 | from_hex(&hi, hi_str); |
74 | 6 | from_hex(&lo, lo_str); |
75 | 6 | } |
76 | | |
77 | | bool initialized() const { return hi != 0 || lo != 0; } |
78 | | |
79 | | // currently, the implementation is uuid, but it may change in the future |
80 | 12.2k | static UniqueId gen_uid() { |
81 | 12.2k | UniqueId uid(0, 0); |
82 | 12.2k | auto uuid = UUIDGenerator::instance()->next_uuid(); |
83 | 12.2k | memcpy(&uid.hi, uuid.data, sizeof(int64_t)); |
84 | 12.2k | memcpy(&uid.lo, uuid.data + sizeof(int64_t), sizeof(int64_t)); |
85 | 12.2k | return uid; |
86 | 12.2k | } |
87 | | |
88 | 30.6k | ~UniqueId() noexcept {} |
89 | | |
90 | 318 | std::string to_string() const { |
91 | 318 | char buf[33]; |
92 | 318 | to_hex(hi, buf); |
93 | 318 | buf[16] = '-'; |
94 | 318 | to_hex(lo, buf + 17); |
95 | 318 | return {buf, 33}; |
96 | 318 | } |
97 | | |
98 | 13.0k | UniqueId& operator=(const UniqueId uid) { |
99 | 13.0k | hi = uid.hi; |
100 | 13.0k | lo = uid.lo; |
101 | 13.0k | return *this; |
102 | 13.0k | } |
103 | | |
104 | | UniqueId& operator=(const PUniqueId puid) { |
105 | | hi = puid.hi(); |
106 | | lo = puid.lo(); |
107 | | return *this; |
108 | | } |
109 | | |
110 | | UniqueId& operator=(const TUniqueId tuid) { |
111 | | hi = tuid.hi; |
112 | | lo = tuid.lo; |
113 | | return *this; |
114 | | } |
115 | | //compare PUniqueId and UniqueId |
116 | | bool operator==(const PUniqueId& rhs) const { return hi == rhs.hi() && lo == rhs.lo(); } |
117 | | |
118 | | bool operator!=(const PUniqueId& rhs) const { return hi != rhs.hi() || lo != rhs.lo(); } |
119 | | |
120 | | // std::map std::set needs this operator |
121 | | bool operator<(const UniqueId& right) const { |
122 | | if (hi != right.hi) { |
123 | | return hi < right.hi; |
124 | | } else { |
125 | | return lo < right.lo; |
126 | | } |
127 | | } |
128 | | |
129 | | // std::unordered_map need this api |
130 | | size_t hash(size_t seed = 0) const; |
131 | | |
132 | | // std::unordered_map need this api |
133 | 52 | bool operator==(const UniqueId& rhs) const { return hi == rhs.hi && lo == rhs.lo; } |
134 | | |
135 | 88 | bool operator!=(const UniqueId& rhs) const { return hi != rhs.hi || lo != rhs.lo; } |
136 | | |
137 | | TUniqueId to_thrift() const { |
138 | | TUniqueId tid; |
139 | | tid.__set_hi(hi); |
140 | | tid.__set_lo(lo); |
141 | | return tid; |
142 | | } |
143 | | |
144 | 1.39k | PUniqueId to_proto() const { |
145 | 1.39k | PUniqueId pid; |
146 | 1.39k | pid.set_hi(hi); |
147 | 1.39k | pid.set_lo(lo); |
148 | 1.39k | return pid; |
149 | 1.39k | } |
150 | | }; |
151 | | |
152 | | // This function must be called 'hash_value' to be picked up by boost. |
153 | | std::size_t hash_value(const doris::TUniqueId& id); |
154 | | |
155 | | /// generates a 16 byte UUID |
156 | | inline std::string generate_uuid_string() { |
157 | | return boost::uuids::to_string(boost::uuids::basic_random_generator<boost::mt19937>()()); |
158 | | } |
159 | | |
160 | | /// generates a 16 byte UUID |
161 | 0 | inline TUniqueId generate_uuid() { |
162 | 0 | auto uuid = boost::uuids::basic_random_generator<boost::mt19937>()(); |
163 | 0 | TUniqueId uid; |
164 | 0 | memcpy(&uid.hi, uuid.data, sizeof(int64_t)); |
165 | 0 | memcpy(&uid.lo, uuid.data + sizeof(int64_t), sizeof(int64_t)); |
166 | 0 | return uid; |
167 | 0 | } |
168 | | |
169 | | std::ostream& operator<<(std::ostream& os, const UniqueId& uid); |
170 | | |
171 | | std::string print_id(const TUniqueId& id); |
172 | | std::string print_id(const PUniqueId& id); |
173 | | |
174 | | // Parse 's' into a TUniqueId object. The format of s needs to be the output format |
175 | | // from PrintId. (<hi_part>:<low_part>) |
176 | | // Returns true if parse succeeded. |
177 | | bool parse_id(const std::string& s, TUniqueId* id); |
178 | | |
179 | | } // namespace doris |
180 | | |
181 | | template <> |
182 | | struct std::hash<doris::UniqueId> { |
183 | 132 | size_t operator()(const doris::UniqueId& uid) const { return uid.hash(); } |
184 | | }; |