Coverage Report

Created: 2026-10-29 13:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/storage/utils.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
// IWYU pragma: no_include <bthread/errno.h>
21
#include <errno.h> // IWYU pragma: keep
22
#include <limits.h>
23
#include <stdint.h>
24
#include <sys/time.h>
25
26
#include <cstdio>
27
#include <cstdlib>
28
#include <iterator>
29
#include <limits>
30
#include <string>
31
#include <vector>
32
33
#include "common/status.h"
34
#include "storage/olap_common.h"
35
36
namespace doris {
37
static const std::string DELETE_SIGN = "__DORIS_DELETE_SIGN__";
38
static const std::string WHERE_SIGN = "__DORIS_WHERE_SIGN__";
39
static const std::string VERSION_COL = "__DORIS_VERSION_COL__";
40
static const std::string SKIP_BITMAP_COL = "__DORIS_SKIP_BITMAP_COL__";
41
static const std::string SEQUENCE_COL = "__DORIS_SEQUENCE_COL__";
42
static const std::string COMMIT_TSO_COL = "__DORIS_COMMIT_TSO_COL__";
43
static const std::string ROW_LSN_COL = "__DORIS_ROW_LSN_COL__";
44
static const std::string TTL_COL = "__DORIS_TTL_COL__";
45
// ATTN(changelog-rename): formerly "__DORIS_BINLOG_TSO__"
46
static const std::string CHANGELOG_TSO_COL = "__DORIS_CHANGELOG_TSO__";
47
// ATTN(changelog-rename): formerly "__DORIS_BINLOG_LSN__"
48
static const std::string CHANGELOG_LSN_COL = "__DORIS_CHANGELOG_LSN__";
49
// ATTN(changelog-rename): formerly "__DORIS_BINLOG_OP__"
50
static const std::string CHANGELOG_OP_COL = "__DORIS_CHANGELOG_OP__";
51
52
// 用来加速运算
53
const static int32_t g_power_table[] = {1,      10,      100,      1000,      10000,
54
                                        100000, 1000000, 10000000, 100000000, 1000000000};
55
56
// 计时工具,用于确定一段代码执行的时间,用于性能调优
57
class OlapStopWatch {
58
public:
59
224k
    uint64_t get_elapse_time_us() const {
60
224k
        struct timeval now;
61
224k
        gettimeofday(&now, nullptr);
62
224k
        return (uint64_t)((now.tv_sec - _begin_time.tv_sec) * 1e6 +
63
224k
                          (now.tv_usec - _begin_time.tv_usec));
64
224k
    }
65
66
353
    double get_elapse_second() const { return get_elapse_time_us() / 1000000.0; }
67
68
120k
    void reset() { gettimeofday(&_begin_time, nullptr); }
69
70
120k
    OlapStopWatch() { reset(); }
71
72
private:
73
    struct timeval _begin_time; // 起始时间戳
74
};
75
76
// @brief 切分字符串
77
// @param base 原串
78
// @param separator 分隔符
79
// @param result 切分结果
80
template <typename Str, typename T>
81
307k
Status split_string(const Str& base, const T separator, std::vector<std::string>* result) {
82
307k
    if (!result) {
83
0
        return Status::Error<ErrorCode::INVALID_ARGUMENT>("split_string meet nullptr result input");
84
0
    }
85
86
    // 处理base为空的情况
87
    // 在删除功能中,当varchar类型列的过滤条件为空时,会出现这种情况
88
307k
    if (base.size() == 0) {
89
0
        result->push_back("");
90
0
        return Status::OK();
91
0
    }
92
93
307k
    size_t offset = 0;
94
916k
    while (offset < base.length()) {
95
916k
        size_t next = base.find(separator, offset);
96
916k
        if (next == std::string::npos) {
97
307k
            result->emplace_back(base.substr(offset));
98
307k
            break;
99
609k
        } else {
100
609k
            result->emplace_back(base.substr(offset, next - offset));
101
609k
            offset = next + 1;
102
609k
        }
103
916k
    }
104
105
307k
    return Status::OK();
106
307k
}
_ZN5doris12split_stringISt17basic_string_viewIcSt11char_traitsIcEEcEENS_6StatusERKT_T0_PSt6vectorINSt7__cxx1112basic_stringIcS3_SaIcEEESaISE_EE
Line
Count
Source
81
302k
Status split_string(const Str& base, const T separator, std::vector<std::string>* result) {
82
302k
    if (!result) {
83
0
        return Status::Error<ErrorCode::INVALID_ARGUMENT>("split_string meet nullptr result input");
84
0
    }
85
86
    // 处理base为空的情况
87
    // 在删除功能中,当varchar类型列的过滤条件为空时,会出现这种情况
88
302k
    if (base.size() == 0) {
89
0
        result->push_back("");
90
0
        return Status::OK();
91
0
    }
92
93
302k
    size_t offset = 0;
94
906k
    while (offset < base.length()) {
95
906k
        size_t next = base.find(separator, offset);
96
906k
        if (next == std::string::npos) {
97
302k
            result->emplace_back(base.substr(offset));
98
302k
            break;
99
604k
        } else {
100
604k
            result->emplace_back(base.substr(offset, next - offset));
101
604k
            offset = next + 1;
102
604k
        }
103
906k
    }
104
105
302k
    return Status::OK();
106
302k
}
_ZN5doris12split_stringINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEcEENS_6StatusERKT_T0_PSt6vectorIS6_SaIS6_EE
Line
Count
Source
81
4.88k
Status split_string(const Str& base, const T separator, std::vector<std::string>* result) {
82
4.88k
    if (!result) {
83
0
        return Status::Error<ErrorCode::INVALID_ARGUMENT>("split_string meet nullptr result input");
84
0
    }
85
86
    // 处理base为空的情况
87
    // 在删除功能中,当varchar类型列的过滤条件为空时,会出现这种情况
88
4.88k
    if (base.size() == 0) {
89
0
        result->push_back("");
90
0
        return Status::OK();
91
0
    }
92
93
4.88k
    size_t offset = 0;
94
9.76k
    while (offset < base.length()) {
95
9.76k
        size_t next = base.find(separator, offset);
96
9.76k
        if (next == std::string::npos) {
97
4.88k
            result->emplace_back(base.substr(offset));
98
4.88k
            break;
99
4.88k
        } else {
100
4.88k
            result->emplace_back(base.substr(offset, next - offset));
101
4.88k
            offset = next + 1;
102
4.88k
        }
103
9.76k
    }
104
105
4.88k
    return Status::OK();
106
4.88k
}
107
108
uint32_t olap_adler32_init();
109
uint32_t olap_adler32(uint32_t adler, const char* buf, size_t len);
110
111
// 获取系统当前时间,并将时间转换为字符串
112
Status gen_timestamp_string(std::string* out_string);
113
114
Status check_datapath_rw(const std::string& path);
115
116
Status read_write_test_file(const std::string& test_file_path);
117
118
// 打印Errno
119
class Errno {
120
public:
121
    // 返回Errno对应的错误信息,线程安全
122
    static const char* str();
123
    static const char* str(int no);
124
    static int no();
125
126
private:
127
    static const int BUF_SIZE = 256;
128
    static __thread char _buf[BUF_SIZE];
129
};
130
131
// 检查int8_t, int16_t, int32_t, int64_t的值是否溢出
132
template <typename T>
133
917
bool valid_signed_number(const std::string& value_str) {
134
917
    char* endptr = nullptr;
135
917
    errno = 0;
136
917
    int64_t value = strtol(value_str.c_str(), &endptr, 10);
137
138
917
    if ((errno == ERANGE && (value == LONG_MAX || value == LONG_MIN)) ||
139
921
        (errno != 0 && value == 0) || endptr == value_str || *endptr != '\0') {
140
2
        return false;
141
2
    }
142
143
916
    if (value < std::numeric_limits<T>::min() || value > std::numeric_limits<T>::max()) {
144
6
        return false;
145
6
    }
146
147
909
    return true;
148
915
}
_ZN5doris19valid_signed_numberIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
133
64
bool valid_signed_number(const std::string& value_str) {
134
64
    char* endptr = nullptr;
135
64
    errno = 0;
136
64
    int64_t value = strtol(value_str.c_str(), &endptr, 10);
137
138
64
    if ((errno == ERANGE && (value == LONG_MAX || value == LONG_MIN)) ||
139
64
        (errno != 0 && value == 0) || endptr == value_str || *endptr != '\0') {
140
2
        return false;
141
2
    }
142
143
63
    if (value < std::numeric_limits<T>::min() || value > std::numeric_limits<T>::max()) {
144
0
        return false;
145
0
    }
146
147
62
    return true;
148
62
}
_ZN5doris19valid_signed_numberIaEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
133
25
bool valid_signed_number(const std::string& value_str) {
134
25
    char* endptr = nullptr;
135
25
    errno = 0;
136
25
    int64_t value = strtol(value_str.c_str(), &endptr, 10);
137
138
25
    if ((errno == ERANGE && (value == LONG_MAX || value == LONG_MIN)) ||
139
25
        (errno != 0 && value == 0) || endptr == value_str || *endptr != '\0') {
140
0
        return false;
141
0
    }
142
143
25
    if (value < std::numeric_limits<T>::min() || value > std::numeric_limits<T>::max()) {
144
2
        return false;
145
2
    }
146
147
23
    return true;
148
25
}
_ZN5doris19valid_signed_numberIsEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
133
17
bool valid_signed_number(const std::string& value_str) {
134
17
    char* endptr = nullptr;
135
17
    errno = 0;
136
17
    int64_t value = strtol(value_str.c_str(), &endptr, 10);
137
138
17
    if ((errno == ERANGE && (value == LONG_MAX || value == LONG_MIN)) ||
139
17
        (errno != 0 && value == 0) || endptr == value_str || *endptr != '\0') {
140
0
        return false;
141
0
    }
142
143
17
    if (value < std::numeric_limits<T>::min() || value > std::numeric_limits<T>::max()) {
144
2
        return false;
145
2
    }
146
147
15
    return true;
148
17
}
_ZN5doris19valid_signed_numberIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
133
811
bool valid_signed_number(const std::string& value_str) {
134
811
    char* endptr = nullptr;
135
811
    errno = 0;
136
811
    int64_t value = strtol(value_str.c_str(), &endptr, 10);
137
138
811
    if ((errno == ERANGE && (value == LONG_MAX || value == LONG_MIN)) ||
139
816
        (errno != 0 && value == 0) || endptr == value_str || *endptr != '\0') {
140
0
        return false;
141
0
    }
142
143
813
    if (value < std::numeric_limits<T>::min() || value > std::numeric_limits<T>::max()) {
144
2
        return false;
145
2
    }
146
147
809
    return true;
148
811
}
149
150
template <>
151
bool valid_signed_number<int128_t>(const std::string& value_str);
152
153
// 检查uint8_t, uint16_t, uint32_t, uint64_t的值是否溢出
154
template <typename T>
155
0
bool valid_unsigned_number(const std::string& value_str) {
156
0
    if (value_str[0] == '-') {
157
0
        return false;
158
0
    }
159
160
0
    char* endptr = nullptr;
161
0
    errno = 0;
162
0
    uint64_t value = strtoul(value_str.c_str(), &endptr, 10);
163
164
0
    if ((errno == ERANGE && (value == ULONG_MAX)) || (errno != 0 && value == 0) ||
165
0
        endptr == value_str || *endptr != '\0') {
166
0
        return false;
167
0
    }
168
169
0
    if (value < std::numeric_limits<T>::min() || value > std::numeric_limits<T>::max()) {
170
0
        return false;
171
0
    }
172
173
0
    return true;
174
0
}
Unexecuted instantiation: _ZN5doris21valid_unsigned_numberIhEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris21valid_unsigned_numberItEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris21valid_unsigned_numberIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris21valid_unsigned_numberImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
175
176
bool valid_decimal(const std::string& value_str, const uint32_t precision, const uint32_t frac);
177
178
// Validate date/datetime format and fractional-second scale roughly.
179
bool valid_datetime(const std::string& value_str, const uint32_t scale);
180
181
bool valid_bool(const std::string& value_str);
182
183
bool valid_ipv4(const std::string& value_str);
184
185
bool valid_ipv6(const std::string& value_str);
186
187
bool valid_uuid(const std::string& value_str);
188
189
19.3M
constexpr bool is_string_type(const FieldType& field_type) {
190
19.3M
    return field_type == FieldType::OLAP_FIELD_TYPE_VARCHAR ||
191
19.3M
           field_type == FieldType::OLAP_FIELD_TYPE_CHAR ||
192
19.3M
           field_type == FieldType::OLAP_FIELD_TYPE_STRING;
193
19.3M
}
194
195
// Util used to get string name of thrift enum item
196
#define EnumToString(enum_type, index, out)                   \
197
36.0M
    do {                                                      \
198
36.0M
        auto it = _##enum_type##_VALUES_TO_NAMES.find(index); \
199
36.0M
        if (it == _##enum_type##_VALUES_TO_NAMES.end()) {     \
200
0
            out = "NULL";                                     \
201
36.0M
        } else {                                              \
202
36.0M
            out = it->second;                                 \
203
36.0M
        }                                                     \
204
36.0M
    } while (0)
205
206
struct RowLocation {
207
14.1M
    RowLocation() : segment_id(0), row_id(0) {}
208
    RowLocation(uint32_t sid, uint32_t rid) : segment_id(sid), row_id(rid) {}
209
    RowLocation(RowsetId rsid, uint32_t sid, uint32_t rid)
210
11.1M
            : rowset_id(rsid), segment_id(sid), row_id(rid) {}
211
    RowsetId rowset_id;
212
    uint32_t segment_id;
213
    uint32_t row_id;
214
215
    bool operator==(const RowLocation& rhs) const {
216
        return rowset_id == rhs.rowset_id && segment_id == rhs.segment_id && row_id == rhs.row_id;
217
    }
218
219
943
    bool operator<(const RowLocation& rhs) const {
220
943
        if (rowset_id != rhs.rowset_id) {
221
90
            return rowset_id < rhs.rowset_id;
222
853
        } else if (segment_id != rhs.segment_id) {
223
0
            return segment_id < rhs.segment_id;
224
853
        } else {
225
853
            return row_id < rhs.row_id;
226
853
        }
227
943
    }
228
};
229
using RowLocationSet = std::set<RowLocation>;
230
using RowLocationPairList = std::list<std::pair<RowLocation, RowLocation>>;
231
232
struct GlobalRowLoacationV2 {
233
    GlobalRowLoacationV2(uint8_t ver, uint64_t bid, uint32_t fid, uint32_t rid)
234
24.5M
            : version(ver), backend_id(bid), file_id(fid), row_id(rid) {}
235
    uint8_t version;
236
    int64_t backend_id;
237
    uint32_t file_id;
238
    uint32_t row_id;
239
240
    auto operator<=>(const GlobalRowLoacationV2&) const = default;
241
};
242
243
} // namespace doris