Line | Count | Source |
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 <stdint.h> |
21 | | |
22 | | #include <boost/random/mersenne_twister.hpp> |
23 | | #include <boost/uuid/random_generator.hpp> |
24 | | #include <boost/uuid/uuid.hpp> |
25 | | #include <boost/uuid/uuid_io.hpp> |
26 | | #include <cstring> |
27 | | #include <ostream> |
28 | | #include <string> |
29 | | #include <string_view> |
30 | | |
31 | | #include "util/uuid_generator.h" |
32 | | |
33 | | namespace doris { |
34 | | |
35 | | class TUniqueId; |
36 | | class PUniqueId; |
37 | | |
38 | | // convert int to a hex format string, buf must enough to hold converted hex string |
39 | | template <typename T> |
40 | 31.8M | void to_hex(T val, char* buf) { |
41 | 31.8M | static const char* digits = "0123456789abcdef"; |
42 | 540M | for (size_t i = 0; i < 2 * sizeof(T); ++i) { |
43 | 508M | buf[2 * sizeof(T) - 1 - i] = digits[val & 0x0F]; |
44 | 508M | val >>= 4; |
45 | 508M | } |
46 | 31.8M | } |
47 | | |
48 | | template <typename T> |
49 | 2.59M | void from_hex(T* ret, std::string_view buf) { |
50 | 2.59M | T val = 0; |
51 | 41.4M | for (char i : buf) { |
52 | 41.4M | int buf_val = 0; |
53 | 41.4M | if (i >= '0' && i <= '9') { |
54 | 30.2M | buf_val = i - '0'; |
55 | 30.2M | } else { |
56 | 11.2M | buf_val = i - 'a' + 10; |
57 | 11.2M | } |
58 | 41.4M | val <<= 4; |
59 | 41.4M | val = val | buf_val; |
60 | 41.4M | } |
61 | 2.59M | *ret = val; |
62 | 2.59M | } |
63 | | |
64 | | struct UniqueId { |
65 | | int64_t hi = 0; |
66 | | int64_t lo = 0; |
67 | | |
68 | 3.34M | UniqueId() = default; |
69 | 5.27M | UniqueId(int64_t hi_, int64_t lo_) : hi(hi_), lo(lo_) {} |
70 | 8.89M | UniqueId(const UniqueId& uid) : hi(uid.hi), lo(uid.lo) {} |
71 | | UniqueId(const TUniqueId& tuid); |
72 | | UniqueId(const PUniqueId& puid); |
73 | 6.38k | UniqueId(const std::string& hi_str, const std::string& lo_str) { |
74 | 6.38k | from_hex(&hi, hi_str); |
75 | 6.38k | from_hex(&lo, lo_str); |
76 | 6.38k | } |
77 | | |
78 | 3.33M | bool initialized() const { return hi != 0 || lo != 0; } |
79 | | |
80 | | // currently, the implementation is uuid, but it may change in the future |
81 | 3.89M | static UniqueId gen_uid() { |
82 | 3.89M | UniqueId uid(0, 0); |
83 | 3.89M | auto uuid = UUIDGenerator::instance()->next_uuid(); |
84 | 3.89M | memcpy(&uid.hi, uuid.data, sizeof(int64_t)); |
85 | 3.89M | memcpy(&uid.lo, uuid.data + sizeof(int64_t), sizeof(int64_t)); |
86 | 3.89M | return uid; |
87 | 3.89M | } |
88 | | |
89 | 18.3M | ~UniqueId() noexcept {} |
90 | | |
91 | 6.23M | std::string to_string() const { |
92 | 6.23M | char buf[33]; |
93 | 6.23M | to_hex(hi, buf); |
94 | 6.23M | buf[16] = '-'; |
95 | 6.23M | to_hex(lo, buf + 17); |
96 | 6.23M | return {buf, 33}; |
97 | 6.23M | } |
98 | | |
99 | 3.52M | UniqueId& operator=(const UniqueId uid) { |
100 | 3.52M | hi = uid.hi; |
101 | 3.52M | lo = uid.lo; |
102 | 3.52M | return *this; |
103 | 3.52M | } |
104 | | |
105 | | UniqueId& operator=(const PUniqueId puid); |
106 | | |
107 | | UniqueId& operator=(const TUniqueId tuid); |
108 | | //compare PUniqueId and UniqueId |
109 | | bool operator==(const PUniqueId& rhs) const; |
110 | | |
111 | | bool operator!=(const PUniqueId& rhs) const; |
112 | | |
113 | | // std::map std::set needs this operator |
114 | 26.0k | bool operator<(const UniqueId& right) const { |
115 | 26.0k | if (hi != right.hi) { |
116 | 7.80k | return hi < right.hi; |
117 | 18.2k | } else { |
118 | 18.2k | return lo < right.lo; |
119 | 18.2k | } |
120 | 26.0k | } |
121 | | |
122 | | // std::unordered_map need this api |
123 | | size_t hash(size_t seed = 0) const; |
124 | | |
125 | | // std::unordered_map need this api |
126 | 138k | bool operator==(const UniqueId& rhs) const { return hi == rhs.hi && lo == rhs.lo; } |
127 | | |
128 | 13.8k | bool operator!=(const UniqueId& rhs) const { return hi != rhs.hi || lo != rhs.lo; } |
129 | | |
130 | | TUniqueId to_thrift() const; |
131 | | |
132 | | PUniqueId to_proto() const; |
133 | | }; |
134 | | |
135 | | // This function must be called 'hash_value' to be picked up by boost. |
136 | | std::size_t hash_value(const doris::TUniqueId& id); |
137 | | |
138 | | /// generates a 16 byte UUID |
139 | 1.41k | inline std::string generate_uuid_string() { |
140 | 1.41k | return boost::uuids::to_string(boost::uuids::basic_random_generator<boost::mt19937>()()); |
141 | 1.41k | } |
142 | | |
143 | | /// generates a 16 byte UUID |
144 | | TUniqueId generate_uuid(); |
145 | | |
146 | | std::ostream& operator<<(std::ostream& os, const UniqueId& uid); |
147 | | |
148 | | std::string print_id(const UniqueId& id); |
149 | | std::string print_id(const TUniqueId& id); |
150 | | std::string print_id(const PUniqueId& id); |
151 | | |
152 | | } // namespace doris |
153 | | |
154 | | template <> |
155 | | struct std::hash<doris::UniqueId> { |
156 | 573k | size_t operator()(const doris::UniqueId& uid) const { return uid.hash(); } |
157 | | }; |