/root/doris/be/src/util/uid_util.h
| 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 <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 | 68.7k | void to_hex(T val, char* buf) { | 
| 40 | 68.7k |     static const char* digits = "0123456789abcdef"; | 
| 41 | 1.16M |     for (int i = 0; i < 2 * sizeof(T); ++i) { | 
| 42 | 1.10M |         buf[2 * sizeof(T) - 1 - i] = digits[val & 0x0F]; | 
| 43 | 1.10M |         val >>= 4; | 
| 44 | 1.10M |     } | 
| 45 | 68.7k | } | 
| 46 |  |  | 
| 47 |  | template <typename T> | 
| 48 | 34.1k | void from_hex(T* ret, std::string_view buf) { | 
| 49 | 34.1k |     T val = 0; | 
| 50 | 546k |     for (char i : buf) { | 
| 51 | 546k |         int buf_val = 0; | 
| 52 | 546k |         if (i >= '0' && i <= '9') { | 
| 53 | 437k |             buf_val = i - '0'; | 
| 54 | 437k |         } else { | 
| 55 | 109k |             buf_val = i - 'a' + 10; | 
| 56 | 109k |         } | 
| 57 | 546k |         val <<= 4; | 
| 58 | 546k |         val = val | buf_val; | 
| 59 | 546k |     } | 
| 60 | 34.1k |     *ret = val; | 
| 61 | 34.1k | } | 
| 62 |  |  | 
| 63 |  | struct UniqueId { | 
| 64 |  |     int64_t hi = 0; | 
| 65 |  |     int64_t lo = 0; | 
| 66 |  |  | 
| 67 | 616k |     UniqueId() = default; | 
| 68 | 619k |     UniqueId(int64_t hi_, int64_t lo_) : hi(hi_), lo(lo_) {} | 
| 69 | 19.5k |     UniqueId(const UniqueId& uid) : hi(uid.hi), lo(uid.lo) {} | 
| 70 | 33 |     UniqueId(const TUniqueId& tuid) : hi(tuid.hi), lo(tuid.lo) {} | 
| 71 | 1.30k |     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 | 827 |     bool initialized() const { return hi != 0 || lo != 0; } | 
| 78 |  |  | 
| 79 |  |     // currently, the implementation is uuid, but it may change in the future | 
| 80 | 616k |     static UniqueId gen_uid() { | 
| 81 | 616k |         UniqueId uid(0, 0); | 
| 82 | 616k |         auto uuid = UUIDGenerator::instance()->next_uuid(); | 
| 83 | 616k |         memcpy(&uid.hi, uuid.data, sizeof(int64_t)); | 
| 84 | 616k |         memcpy(&uid.lo, uuid.data + sizeof(int64_t), sizeof(int64_t)); | 
| 85 | 616k |         return uid; | 
| 86 | 616k |     } | 
| 87 |  |  | 
| 88 | 1.25M |     ~UniqueId() noexcept {} | 
| 89 |  |  | 
| 90 | 903 |     std::string to_string() const { | 
| 91 | 903 |         char buf[33]; | 
| 92 | 903 |         to_hex(hi, buf); | 
| 93 | 903 |         buf[16] = '-'; | 
| 94 | 903 |         to_hex(lo, buf + 17); | 
| 95 | 903 |         return {buf, 33}; | 
| 96 | 903 |     } | 
| 97 |  |  | 
| 98 | 617k |     UniqueId& operator=(const UniqueId uid) { | 
| 99 | 617k |         hi = uid.hi; | 
| 100 | 617k |         lo = uid.lo; | 
| 101 | 617k |         return *this; | 
| 102 | 617k |     } | 
| 103 |  |  | 
| 104 | 0 |     UniqueId& operator=(const PUniqueId puid) { | 
| 105 | 0 |         hi = puid.hi(); | 
| 106 | 0 |         lo = puid.lo(); | 
| 107 | 0 |         return *this; | 
| 108 | 0 |     } | 
| 109 |  |  | 
| 110 | 0 |     UniqueId& operator=(const TUniqueId tuid) { | 
| 111 | 0 |         hi = tuid.hi; | 
| 112 | 0 |         lo = tuid.lo; | 
| 113 | 0 |         return *this; | 
| 114 | 0 |     } | 
| 115 |  |     //compare PUniqueId and UniqueId | 
| 116 | 0 |     bool operator==(const PUniqueId& rhs) const { return hi == rhs.hi() && lo == rhs.lo(); } | 
| 117 |  |  | 
| 118 | 24 |     bool operator!=(const PUniqueId& rhs) const { return hi != rhs.hi() || lo != rhs.lo(); } | 
| 119 |  |  | 
| 120 |  |     // std::map std::set needs this operator | 
| 121 | 1.23k |     bool operator<(const UniqueId& right) const { | 
| 122 | 1.23k |         if (hi != right.hi) { | 
| 123 | 0 |             return hi < right.hi; | 
| 124 | 1.23k |         } else { | 
| 125 | 1.23k |             return lo < right.lo; | 
| 126 | 1.23k |         } | 
| 127 | 1.23k |     } | 
| 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 | 403 |     bool operator==(const UniqueId& rhs) const { return hi == rhs.hi && lo == rhs.lo; } | 
| 134 |  |  | 
| 135 | 292 |     bool operator!=(const UniqueId& rhs) const { return hi != rhs.hi || lo != rhs.lo; } | 
| 136 |  |  | 
| 137 | 15 |     TUniqueId to_thrift() const { | 
| 138 | 15 |         TUniqueId tid; | 
| 139 | 15 |         tid.__set_hi(hi); | 
| 140 | 15 |         tid.__set_lo(lo); | 
| 141 | 15 |         return tid; | 
| 142 | 15 |     } | 
| 143 |  |  | 
| 144 | 13.0k |     PUniqueId to_proto() const { | 
| 145 | 13.0k |         PUniqueId pid; | 
| 146 | 13.0k |         pid.set_hi(hi); | 
| 147 | 13.0k |         pid.set_lo(lo); | 
| 148 | 13.0k |         return pid; | 
| 149 | 13.0k |     } | 
| 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 | 3 | inline std::string generate_uuid_string() { | 
| 157 | 3 |     return boost::uuids::to_string(boost::uuids::basic_random_generator<boost::mt19937>()()); | 
| 158 | 3 | } | 
| 159 |  |  | 
| 160 |  | /// generates a 16 byte UUID | 
| 161 | 105 | inline TUniqueId generate_uuid() { | 
| 162 | 105 |     auto uuid = boost::uuids::basic_random_generator<boost::mt19937>()(); | 
| 163 | 105 |     TUniqueId uid; | 
| 164 | 105 |     memcpy(&uid.hi, uuid.data, sizeof(int64_t)); | 
| 165 | 105 |     memcpy(&uid.lo, uuid.data + sizeof(int64_t), sizeof(int64_t)); | 
| 166 | 105 |     return uid; | 
| 167 | 105 | } | 
| 168 |  |  | 
| 169 |  | std::ostream& operator<<(std::ostream& os, const UniqueId& uid); | 
| 170 |  |  | 
| 171 |  | std::string print_id(const UniqueId& id); | 
| 172 |  | std::string print_id(const TUniqueId& id); | 
| 173 |  | std::string print_id(const PUniqueId& id); | 
| 174 |  |  | 
| 175 |  | } // namespace doris | 
| 176 |  |  | 
| 177 |  | template <> | 
| 178 |  | struct std::hash<doris::UniqueId> { | 
| 179 | 952 |     size_t operator()(const doris::UniqueId& uid) const { return uid.hash(); } | 
| 180 |  | }; |