/root/doris/be/src/olap/uint24.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 <fmt/compile.h> | 
| 21 |  |  | 
| 22 |  | #include <cstdint> | 
| 23 |  | #include <cstring> | 
| 24 |  | #include <iostream> | 
| 25 |  | #include <string> | 
| 26 |  |  | 
| 27 |  | namespace doris { | 
| 28 |  |  | 
| 29 |  | // 24bit int type, used to store date type in storage | 
| 30 |  | struct uint24_t { | 
| 31 |  | public: | 
| 32 |  |     uint24_t() = default; | 
| 33 |  |  | 
| 34 | 4.64k |     uint24_t(const uint32_t& value) { | 
| 35 | 4.64k |         data[0] = static_cast<uint8_t>(value); | 
| 36 | 4.64k |         data[1] = static_cast<uint8_t>(value >> 8); | 
| 37 | 4.64k |         data[2] = static_cast<uint8_t>(value >> 16); | 
| 38 | 4.64k |     } | 
| 39 |  |  | 
| 40 | 0 |     uint24_t& operator=(const uint32_t value) { | 
| 41 | 0 |         data[0] = static_cast<uint8_t>(value); | 
| 42 | 0 |         data[1] = static_cast<uint8_t>(value >> 8); | 
| 43 | 0 |         data[2] = static_cast<uint8_t>(value >> 16); | 
| 44 | 0 |         return *this; | 
| 45 | 0 |     } | 
| 46 |  |  | 
| 47 | 0 |     uint24_t& operator=(const unsigned __int128& value) { | 
| 48 | 0 |         data[0] = static_cast<uint8_t>(value); | 
| 49 | 0 |         data[1] = static_cast<uint8_t>(value >> 8); | 
| 50 | 0 |         data[2] = static_cast<uint8_t>(value >> 16); | 
| 51 | 0 |         return *this; | 
| 52 | 0 |     } | 
| 53 |  |  | 
| 54 | 8 |     uint24_t& operator=(const uint64_t value) { | 
| 55 | 8 |         data[0] = static_cast<uint8_t>(value); | 
| 56 | 8 |         data[1] = static_cast<uint8_t>(value >> 8); | 
| 57 | 8 |         data[2] = static_cast<uint8_t>(value >> 16); | 
| 58 | 8 |         return *this; | 
| 59 | 8 |     } | 
| 60 |  |  | 
| 61 | 0 |     uint24_t& operator+=(const uint24_t& value) { | 
| 62 | 0 |         *this = static_cast<int>(*this) + static_cast<int>(value); | 
| 63 | 0 |         return *this; | 
| 64 | 0 |     } | 
| 65 |  |  | 
| 66 | 0 |     uint24_t& operator>>=(const int bits) { | 
| 67 | 0 |         *this = static_cast<unsigned int>(*this) >> bits; | 
| 68 | 0 |         return *this; | 
| 69 | 0 |     } | 
| 70 |  |  | 
| 71 | 0 |     uint24_t& operator|=(const uint24_t& value) { | 
| 72 | 0 |         *this = static_cast<int>(*this) | static_cast<int>(value); | 
| 73 | 0 |         return *this; | 
| 74 | 0 |     } | 
| 75 |  |  | 
| 76 | 4.43k |     operator uint32_t() const { | 
| 77 | 4.43k |         uint32_t value = static_cast<uint8_t>(data[0]); | 
| 78 | 4.43k |         value += (static_cast<uint32_t>(static_cast<uint8_t>(data[1]))) << 8; | 
| 79 | 4.43k |         value += (static_cast<uint32_t>(static_cast<uint8_t>(data[2]))) << 16; | 
| 80 | 4.43k |         return value; | 
| 81 | 4.43k |     } | 
| 82 |  |  | 
| 83 | 3.09k |     uint24_t& operator=(const int value) { | 
| 84 | 3.09k |         data[0] = static_cast<uint8_t>(value); | 
| 85 | 3.09k |         data[1] = static_cast<uint8_t>(value >> 8); | 
| 86 | 3.09k |         data[2] = static_cast<uint8_t>(value >> 16); | 
| 87 | 3.09k |         return *this; | 
| 88 | 3.09k |     } | 
| 89 |  |  | 
| 90 | 0 |     uint24_t& operator=(const int64_t value) { | 
| 91 | 0 |         data[0] = static_cast<uint8_t>(value); | 
| 92 | 0 |         data[1] = static_cast<uint8_t>(value >> 8); | 
| 93 | 0 |         data[2] = static_cast<uint8_t>(value >> 16); | 
| 94 | 0 |         return *this; | 
| 95 | 0 |     } | 
| 96 |  |  | 
| 97 | 53 |     bool operator==(const uint24_t& value) const { return cmp(value) == 0; } | 
| 98 |  |  | 
| 99 | 0 |     bool operator!=(const uint24_t& value) const { return cmp(value) != 0; } | 
| 100 |  |  | 
| 101 | 95.6k |     bool operator<(const uint24_t& value) const { return cmp(value) < 0; } | 
| 102 |  |  | 
| 103 | 0 |     bool operator<=(const uint24_t& value) const { return cmp(value) <= 0; } | 
| 104 |  |  | 
| 105 | 74 |     bool operator>(const uint24_t& value) const { return cmp(value) > 0; } | 
| 106 |  |  | 
| 107 | 0 |     bool operator>=(const uint24_t& value) const { return cmp(value) >= 0; } | 
| 108 |  |  | 
| 109 | 95.7k |     int32_t cmp(const uint24_t& other) const { | 
| 110 | 95.7k |         if (data[2] > other.data[2]) { | 
| 111 | 138 |             return 1; | 
| 112 | 95.5k |         } else if (data[2] < other.data[2]) { | 
| 113 | 41 |             return -1; | 
| 114 | 41 |         } | 
| 115 |  |  | 
| 116 | 95.5k |         if (data[1] > other.data[1]) { | 
| 117 | 10.8k |             return 1; | 
| 118 | 84.6k |         } else if (data[1] < other.data[1]) { | 
| 119 | 10.8k |             return -1; | 
| 120 | 10.8k |         } | 
| 121 |  |  | 
| 122 | 73.8k |         if (data[0] > other.data[0]) { | 
| 123 | 36.8k |             return 1; | 
| 124 | 36.9k |         } else if (data[0] < other.data[0]) { | 
| 125 | 36.8k |             return -1; | 
| 126 | 36.8k |         } | 
| 127 |  |  | 
| 128 | 57 |         return 0; | 
| 129 | 73.8k |     } | 
| 130 |  |  | 
| 131 | 11 |     std::string to_string() const { | 
| 132 | 11 |         int value = *reinterpret_cast<const uint24_t*>(data); | 
| 133 | 11 |         int mday = value & 31; | 
| 134 | 11 |         int mon = value >> 5 & 15; | 
| 135 | 11 |         int year = value >> 9; | 
| 136 |  |  | 
| 137 | 11 |         return fmt::format(FMT_COMPILE("{:04d}-{:02d}-{:02d}"), year, mon, mday); | 
| 138 | 11 |     } | 
| 139 |  |  | 
| 140 | 0 |     const uint8_t* get_data() const { return data; } | 
| 141 |  |  | 
| 142 |  | private: | 
| 143 |  |     uint8_t data[3]; | 
| 144 |  | } __attribute__((packed)); | 
| 145 |  |  | 
| 146 |  | static_assert(std::is_trivial_v<uint24_t>, "uint24_t should be a POD type"); | 
| 147 |  |  | 
| 148 | 0 | inline std::ostream& operator<<(std::ostream& os, const uint24_t& val) { | 
| 149 | 0 |     os << val.to_string(); | 
| 150 | 0 |     return os; | 
| 151 | 0 | } | 
| 152 |  |  | 
| 153 |  | } // namespace doris |