Coverage Report

Created: 2025-07-23 18:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/doris/be/src/olap/key_coder.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 <glog/logging.h>
21
#include <limits.h>
22
#include <stdint.h>
23
#include <string.h>
24
25
#include <algorithm>
26
#include <ostream>
27
#include <string>
28
#include <type_traits>
29
30
#include "absl/strings/substitute.h"
31
#include "common/status.h"
32
#include "gutil/endian.h"
33
#include "olap/decimal12.h"
34
#include "olap/olap_common.h"
35
#include "olap/types.h"
36
#include "util/slice.h"
37
#include "vec/core/extended_types.h"
38
#include "vec/core/types.h"
39
40
namespace doris {
41
42
using FullEncodeAscendingFunc = void (*)(const void* value, std::string* buf);
43
using EncodeAscendingFunc = void (*)(const void* value, size_t index_size, std::string* buf);
44
using DecodeAscendingFunc = Status (*)(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr);
45
46
// Order-preserving binary encoding for values of a particular type so that
47
// those values can be compared by memcpy their encoded bytes.
48
//
49
// To obtain instance of this class, use the `get_key_coder(FieldType)` method.
50
class KeyCoder {
51
public:
52
    template <typename TraitsType>
53
    KeyCoder(TraitsType traits);
54
55
    // encode the provided `value` into `buf`.
56
969k
    void full_encode_ascending(const void* value, std::string* buf) const {
57
969k
        _full_encode_ascending(value, buf);
58
969k
    }
59
60
    // similar to `full_encode_ascending`, but only encode part (the first `index_size` bytes) of the value.
61
    // only applicable to string type
62
11.9k
    void encode_ascending(const void* value, size_t index_size, std::string* buf) const {
63
11.9k
        _encode_ascending(value, index_size, buf);
64
11.9k
    }
65
66
    // Only used for test, should delete it in the future
67
19
    Status decode_ascending(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr) const {
68
19
        return _decode_ascending(encoded_key, index_size, cell_ptr);
69
19
    }
70
71
private:
72
    FullEncodeAscendingFunc _full_encode_ascending;
73
    EncodeAscendingFunc _encode_ascending;
74
    DecodeAscendingFunc _decode_ascending;
75
};
76
77
extern const KeyCoder* get_key_coder(FieldType type);
78
79
template <FieldType field_type, typename Enable = void>
80
class KeyCoderTraits {};
81
82
template <FieldType field_type>
83
class KeyCoderTraits<
84
        field_type,
85
        typename std::enable_if<
86
                IsIntegral<typename CppTypeTraits<field_type>::CppType>::value ||
87
                vectorized::IsDecimalNumber<typename CppTypeTraits<field_type>::CppType>>::type> {
88
public:
89
    using CppType = typename CppTypeTraits<field_type>::CppType;
90
    using UnsignedCppType = typename CppTypeTraits<field_type>::UnsignedCppType;
91
92
1.02M
    static void full_encode_ascending(const void* value, std::string* buf) {
93
1.02M
        UnsignedCppType unsigned_val;
94
1.02M
        memcpy(&unsigned_val, value, sizeof(unsigned_val));
95
        // swap MSB to encode integer
96
1.02M
        if (IsSigned<CppType>::value) {
97
979k
            unsigned_val ^=
98
979k
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
99
979k
        }
100
        // make it bigendian
101
1.02M
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
102
103
1.02M
        buf->append((char*)&unsigned_val, sizeof(unsigned_val));
104
1.02M
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE7EvE21full_encode_ascendingEPKvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
92
220
    static void full_encode_ascending(const void* value, std::string* buf) {
93
220
        UnsignedCppType unsigned_val;
94
220
        memcpy(&unsigned_val, value, sizeof(unsigned_val));
95
        // swap MSB to encode integer
96
220
        if (IsSigned<CppType>::value) {
97
220
            unsigned_val ^=
98
220
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
99
220
        }
100
        // make it bigendian
101
220
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
102
103
220
        buf->append((char*)&unsigned_val, sizeof(unsigned_val));
104
220
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE5EvE21full_encode_ascendingEPKvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
92
977k
    static void full_encode_ascending(const void* value, std::string* buf) {
93
977k
        UnsignedCppType unsigned_val;
94
977k
        memcpy(&unsigned_val, value, sizeof(unsigned_val));
95
        // swap MSB to encode integer
96
977k
        if (IsSigned<CppType>::value) {
97
977k
            unsigned_val ^=
98
977k
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
99
977k
        }
100
        // make it bigendian
101
977k
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
102
103
977k
        buf->append((char*)&unsigned_val, sizeof(unsigned_val));
104
977k
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE1EvE21full_encode_ascendingEPKvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
92
238
    static void full_encode_ascending(const void* value, std::string* buf) {
93
238
        UnsignedCppType unsigned_val;
94
238
        memcpy(&unsigned_val, value, sizeof(unsigned_val));
95
        // swap MSB to encode integer
96
238
        if (IsSigned<CppType>::value) {
97
238
            unsigned_val ^=
98
238
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
99
238
        }
100
        // make it bigendian
101
238
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
102
103
238
        buf->append((char*)&unsigned_val, sizeof(unsigned_val));
104
238
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE3EvE21full_encode_ascendingEPKvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
92
247
    static void full_encode_ascending(const void* value, std::string* buf) {
93
247
        UnsignedCppType unsigned_val;
94
247
        memcpy(&unsigned_val, value, sizeof(unsigned_val));
95
        // swap MSB to encode integer
96
247
        if (IsSigned<CppType>::value) {
97
247
            unsigned_val ^=
98
247
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
99
247
        }
100
        // make it bigendian
101
247
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
102
103
247
        buf->append((char*)&unsigned_val, sizeof(unsigned_val));
104
247
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE6EvE21full_encode_ascendingEPKvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
92
206
    static void full_encode_ascending(const void* value, std::string* buf) {
93
206
        UnsignedCppType unsigned_val;
94
206
        memcpy(&unsigned_val, value, sizeof(unsigned_val));
95
        // swap MSB to encode integer
96
206
        if (IsSigned<CppType>::value) {
97
0
            unsigned_val ^=
98
0
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
99
0
        }
100
        // make it bigendian
101
206
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
102
103
206
        buf->append((char*)&unsigned_val, sizeof(unsigned_val));
104
206
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE8EvE21full_encode_ascendingEPKvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
92
46.9k
    static void full_encode_ascending(const void* value, std::string* buf) {
93
46.9k
        UnsignedCppType unsigned_val;
94
46.9k
        memcpy(&unsigned_val, value, sizeof(unsigned_val));
95
        // swap MSB to encode integer
96
46.9k
        if (IsSigned<CppType>::value) {
97
0
            unsigned_val ^=
98
0
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
99
0
        }
100
        // make it bigendian
101
46.9k
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
102
103
46.9k
        buf->append((char*)&unsigned_val, sizeof(unsigned_val));
104
46.9k
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE9EvE21full_encode_ascendingEPKvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
92
211
    static void full_encode_ascending(const void* value, std::string* buf) {
93
211
        UnsignedCppType unsigned_val;
94
211
        memcpy(&unsigned_val, value, sizeof(unsigned_val));
95
        // swap MSB to encode integer
96
211
        if (IsSigned<CppType>::value) {
97
211
            unsigned_val ^=
98
211
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
99
211
        }
100
        // make it bigendian
101
211
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
102
103
211
        buf->append((char*)&unsigned_val, sizeof(unsigned_val));
104
211
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE15EvE21full_encode_ascendingEPKvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
92
214
    static void full_encode_ascending(const void* value, std::string* buf) {
93
214
        UnsignedCppType unsigned_val;
94
214
        memcpy(&unsigned_val, value, sizeof(unsigned_val));
95
        // swap MSB to encode integer
96
214
        if (IsSigned<CppType>::value) {
97
214
            unsigned_val ^=
98
214
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
99
214
        }
100
        // make it bigendian
101
214
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
102
103
214
        buf->append((char*)&unsigned_val, sizeof(unsigned_val));
104
214
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE24EvE21full_encode_ascendingEPKvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
92
7
    static void full_encode_ascending(const void* value, std::string* buf) {
93
7
        UnsignedCppType unsigned_val;
94
7
        memcpy(&unsigned_val, value, sizeof(unsigned_val));
95
        // swap MSB to encode integer
96
7
        if (IsSigned<CppType>::value) {
97
0
            unsigned_val ^=
98
0
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
99
0
        }
100
        // make it bigendian
101
7
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
102
103
7
        buf->append((char*)&unsigned_val, sizeof(unsigned_val));
104
7
    }
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE31EvE21full_encode_ascendingEPKvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE32EvE21full_encode_ascendingEPKvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE33EvE21full_encode_ascendingEPKvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE37EvE21full_encode_ascendingEPKvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE38EvE21full_encode_ascendingEPKvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE39EvE21full_encode_ascendingEPKvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
105
106
11.6k
    static void encode_ascending(const void* value, size_t index_size, std::string* buf) {
107
11.6k
        full_encode_ascending(value, buf);
108
11.6k
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE1EvE16encode_ascendingEPKvmPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
106
209
    static void encode_ascending(const void* value, size_t index_size, std::string* buf) {
107
209
        full_encode_ascending(value, buf);
108
209
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE3EvE16encode_ascendingEPKvmPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
106
212
    static void encode_ascending(const void* value, size_t index_size, std::string* buf) {
107
212
        full_encode_ascending(value, buf);
108
212
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE5EvE16encode_ascendingEPKvmPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
106
10.2k
    static void encode_ascending(const void* value, size_t index_size, std::string* buf) {
107
10.2k
        full_encode_ascending(value, buf);
108
10.2k
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE6EvE16encode_ascendingEPKvmPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
106
202
    static void encode_ascending(const void* value, size_t index_size, std::string* buf) {
107
202
        full_encode_ascending(value, buf);
108
202
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE7EvE16encode_ascendingEPKvmPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
106
203
    static void encode_ascending(const void* value, size_t index_size, std::string* buf) {
107
203
        full_encode_ascending(value, buf);
108
203
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE8EvE16encode_ascendingEPKvmPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
106
202
    static void encode_ascending(const void* value, size_t index_size, std::string* buf) {
107
202
        full_encode_ascending(value, buf);
108
202
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE9EvE16encode_ascendingEPKvmPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
106
203
    static void encode_ascending(const void* value, size_t index_size, std::string* buf) {
107
203
        full_encode_ascending(value, buf);
108
203
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE15EvE16encode_ascendingEPKvmPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
106
202
    static void encode_ascending(const void* value, size_t index_size, std::string* buf) {
107
202
        full_encode_ascending(value, buf);
108
202
    }
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE24EvE16encode_ascendingEPKvmPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE31EvE16encode_ascendingEPKvmPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE32EvE16encode_ascendingEPKvmPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE33EvE16encode_ascendingEPKvmPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE37EvE16encode_ascendingEPKvmPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE38EvE16encode_ascendingEPKvmPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE39EvE16encode_ascendingEPKvmPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
109
110
20.3k
    static Status decode_ascending(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr) {
111
        // decode_ascending only used in orinal index page, maybe should remove it in the future.
112
        // currently, we reduce the usage of this method.
113
20.3k
        if (encoded_key->size < sizeof(UnsignedCppType)) {
114
0
            return Status::InvalidArgument("Key too short, need={} vs real={}",
115
0
                                           sizeof(UnsignedCppType), encoded_key->size);
116
0
        }
117
20.3k
        UnsignedCppType unsigned_val;
118
20.3k
        memcpy(&unsigned_val, encoded_key->data, sizeof(UnsignedCppType));
119
20.3k
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
120
20.3k
        if (IsSigned<CppType>::value) {
121
14
            unsigned_val ^=
122
14
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
123
14
        }
124
20.3k
        memcpy(cell_ptr, &unsigned_val, sizeof(UnsignedCppType));
125
20.3k
        encoded_key->remove_prefix(sizeof(UnsignedCppType));
126
20.3k
        return Status::OK();
127
20.3k
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE7EvE16decode_ascendingEPNS_5SliceEmPh
Line
Count
Source
110
3
    static Status decode_ascending(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr) {
111
        // decode_ascending only used in orinal index page, maybe should remove it in the future.
112
        // currently, we reduce the usage of this method.
113
3
        if (encoded_key->size < sizeof(UnsignedCppType)) {
114
0
            return Status::InvalidArgument("Key too short, need={} vs real={}",
115
0
                                           sizeof(UnsignedCppType), encoded_key->size);
116
0
        }
117
3
        UnsignedCppType unsigned_val;
118
3
        memcpy(&unsigned_val, encoded_key->data, sizeof(UnsignedCppType));
119
3
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
120
3
        if (IsSigned<CppType>::value) {
121
3
            unsigned_val ^=
122
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
123
3
        }
124
3
        memcpy(cell_ptr, &unsigned_val, sizeof(UnsignedCppType));
125
3
        encoded_key->remove_prefix(sizeof(UnsignedCppType));
126
3
        return Status::OK();
127
3
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE5EvE16decode_ascendingEPNS_5SliceEmPh
Line
Count
Source
110
3
    static Status decode_ascending(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr) {
111
        // decode_ascending only used in orinal index page, maybe should remove it in the future.
112
        // currently, we reduce the usage of this method.
113
3
        if (encoded_key->size < sizeof(UnsignedCppType)) {
114
0
            return Status::InvalidArgument("Key too short, need={} vs real={}",
115
0
                                           sizeof(UnsignedCppType), encoded_key->size);
116
0
        }
117
3
        UnsignedCppType unsigned_val;
118
3
        memcpy(&unsigned_val, encoded_key->data, sizeof(UnsignedCppType));
119
3
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
120
3
        if (IsSigned<CppType>::value) {
121
3
            unsigned_val ^=
122
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
123
3
        }
124
3
        memcpy(cell_ptr, &unsigned_val, sizeof(UnsignedCppType));
125
3
        encoded_key->remove_prefix(sizeof(UnsignedCppType));
126
3
        return Status::OK();
127
3
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE1EvE16decode_ascendingEPNS_5SliceEmPh
Line
Count
Source
110
2
    static Status decode_ascending(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr) {
111
        // decode_ascending only used in orinal index page, maybe should remove it in the future.
112
        // currently, we reduce the usage of this method.
113
2
        if (encoded_key->size < sizeof(UnsignedCppType)) {
114
0
            return Status::InvalidArgument("Key too short, need={} vs real={}",
115
0
                                           sizeof(UnsignedCppType), encoded_key->size);
116
0
        }
117
2
        UnsignedCppType unsigned_val;
118
2
        memcpy(&unsigned_val, encoded_key->data, sizeof(UnsignedCppType));
119
2
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
120
2
        if (IsSigned<CppType>::value) {
121
2
            unsigned_val ^=
122
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
123
2
        }
124
2
        memcpy(cell_ptr, &unsigned_val, sizeof(UnsignedCppType));
125
2
        encoded_key->remove_prefix(sizeof(UnsignedCppType));
126
2
        return Status::OK();
127
2
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE3EvE16decode_ascendingEPNS_5SliceEmPh
Line
Count
Source
110
2
    static Status decode_ascending(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr) {
111
        // decode_ascending only used in orinal index page, maybe should remove it in the future.
112
        // currently, we reduce the usage of this method.
113
2
        if (encoded_key->size < sizeof(UnsignedCppType)) {
114
0
            return Status::InvalidArgument("Key too short, need={} vs real={}",
115
0
                                           sizeof(UnsignedCppType), encoded_key->size);
116
0
        }
117
2
        UnsignedCppType unsigned_val;
118
2
        memcpy(&unsigned_val, encoded_key->data, sizeof(UnsignedCppType));
119
2
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
120
2
        if (IsSigned<CppType>::value) {
121
2
            unsigned_val ^=
122
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
123
2
        }
124
2
        memcpy(cell_ptr, &unsigned_val, sizeof(UnsignedCppType));
125
2
        encoded_key->remove_prefix(sizeof(UnsignedCppType));
126
2
        return Status::OK();
127
2
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE6EvE16decode_ascendingEPNS_5SliceEmPh
Line
Count
Source
110
2
    static Status decode_ascending(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr) {
111
        // decode_ascending only used in orinal index page, maybe should remove it in the future.
112
        // currently, we reduce the usage of this method.
113
2
        if (encoded_key->size < sizeof(UnsignedCppType)) {
114
0
            return Status::InvalidArgument("Key too short, need={} vs real={}",
115
0
                                           sizeof(UnsignedCppType), encoded_key->size);
116
0
        }
117
2
        UnsignedCppType unsigned_val;
118
2
        memcpy(&unsigned_val, encoded_key->data, sizeof(UnsignedCppType));
119
2
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
120
2
        if (IsSigned<CppType>::value) {
121
0
            unsigned_val ^=
122
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
123
0
        }
124
2
        memcpy(cell_ptr, &unsigned_val, sizeof(UnsignedCppType));
125
2
        encoded_key->remove_prefix(sizeof(UnsignedCppType));
126
2
        return Status::OK();
127
2
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE8EvE16decode_ascendingEPNS_5SliceEmPh
Line
Count
Source
110
20.3k
    static Status decode_ascending(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr) {
111
        // decode_ascending only used in orinal index page, maybe should remove it in the future.
112
        // currently, we reduce the usage of this method.
113
20.3k
        if (encoded_key->size < sizeof(UnsignedCppType)) {
114
0
            return Status::InvalidArgument("Key too short, need={} vs real={}",
115
0
                                           sizeof(UnsignedCppType), encoded_key->size);
116
0
        }
117
20.3k
        UnsignedCppType unsigned_val;
118
20.3k
        memcpy(&unsigned_val, encoded_key->data, sizeof(UnsignedCppType));
119
20.3k
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
120
20.3k
        if (IsSigned<CppType>::value) {
121
0
            unsigned_val ^=
122
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
123
0
        }
124
20.3k
        memcpy(cell_ptr, &unsigned_val, sizeof(UnsignedCppType));
125
20.3k
        encoded_key->remove_prefix(sizeof(UnsignedCppType));
126
20.3k
        return Status::OK();
127
20.3k
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE9EvE16decode_ascendingEPNS_5SliceEmPh
Line
Count
Source
110
2
    static Status decode_ascending(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr) {
111
        // decode_ascending only used in orinal index page, maybe should remove it in the future.
112
        // currently, we reduce the usage of this method.
113
2
        if (encoded_key->size < sizeof(UnsignedCppType)) {
114
0
            return Status::InvalidArgument("Key too short, need={} vs real={}",
115
0
                                           sizeof(UnsignedCppType), encoded_key->size);
116
0
        }
117
2
        UnsignedCppType unsigned_val;
118
2
        memcpy(&unsigned_val, encoded_key->data, sizeof(UnsignedCppType));
119
2
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
120
2
        if (IsSigned<CppType>::value) {
121
2
            unsigned_val ^=
122
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
123
2
        }
124
2
        memcpy(cell_ptr, &unsigned_val, sizeof(UnsignedCppType));
125
2
        encoded_key->remove_prefix(sizeof(UnsignedCppType));
126
2
        return Status::OK();
127
2
    }
_ZN5doris14KeyCoderTraitsILNS_9FieldTypeE15EvE16decode_ascendingEPNS_5SliceEmPh
Line
Count
Source
110
2
    static Status decode_ascending(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr) {
111
        // decode_ascending only used in orinal index page, maybe should remove it in the future.
112
        // currently, we reduce the usage of this method.
113
2
        if (encoded_key->size < sizeof(UnsignedCppType)) {
114
0
            return Status::InvalidArgument("Key too short, need={} vs real={}",
115
0
                                           sizeof(UnsignedCppType), encoded_key->size);
116
0
        }
117
2
        UnsignedCppType unsigned_val;
118
2
        memcpy(&unsigned_val, encoded_key->data, sizeof(UnsignedCppType));
119
2
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
120
2
        if (IsSigned<CppType>::value) {
121
2
            unsigned_val ^=
122
                    (static_cast<UnsignedCppType>(1) << (sizeof(UnsignedCppType) * CHAR_BIT - 1));
123
2
        }
124
2
        memcpy(cell_ptr, &unsigned_val, sizeof(UnsignedCppType));
125
2
        encoded_key->remove_prefix(sizeof(UnsignedCppType));
126
2
        return Status::OK();
127
2
    }
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE24EvE16decode_ascendingEPNS_5SliceEmPh
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE31EvE16decode_ascendingEPNS_5SliceEmPh
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE32EvE16decode_ascendingEPNS_5SliceEmPh
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE33EvE16decode_ascendingEPNS_5SliceEmPh
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE37EvE16decode_ascendingEPNS_5SliceEmPh
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE38EvE16decode_ascendingEPNS_5SliceEmPh
Unexecuted instantiation: _ZN5doris14KeyCoderTraitsILNS_9FieldTypeE39EvE16decode_ascendingEPNS_5SliceEmPh
128
};
129
130
template <>
131
class KeyCoderTraits<FieldType::OLAP_FIELD_TYPE_DATE> {
132
public:
133
    using CppType = typename CppTypeTraits<FieldType::OLAP_FIELD_TYPE_DATE>::CppType;
134
    using UnsignedCppType =
135
            typename CppTypeTraits<FieldType::OLAP_FIELD_TYPE_DATE>::UnsignedCppType;
136
137
public:
138
215
    static void full_encode_ascending(const void* value, std::string* buf) {
139
215
        UnsignedCppType unsigned_val;
140
215
        memcpy(&unsigned_val, value, sizeof(unsigned_val));
141
        // make it bigendian
142
215
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
143
215
        buf->append((char*)&unsigned_val, sizeof(unsigned_val));
144
215
    }
145
146
203
    static void encode_ascending(const void* value, size_t index_size, std::string* buf) {
147
203
        full_encode_ascending(value, buf);
148
203
    }
149
150
2
    static Status decode_ascending(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr) {
151
2
        if (encoded_key->size < sizeof(UnsignedCppType)) {
152
0
            return Status::InvalidArgument("Key too short, need={} vs real={}",
153
0
                                           sizeof(UnsignedCppType), encoded_key->size);
154
0
        }
155
2
        UnsignedCppType unsigned_val;
156
2
        memcpy(&unsigned_val, encoded_key->data, sizeof(UnsignedCppType));
157
2
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
158
2
        memcpy(cell_ptr, &unsigned_val, sizeof(UnsignedCppType));
159
2
        encoded_key->remove_prefix(sizeof(UnsignedCppType));
160
2
        return Status::OK();
161
2
    }
162
};
163
164
template <>
165
class KeyCoderTraits<FieldType::OLAP_FIELD_TYPE_DATEV2> {
166
public:
167
    using CppType = typename CppTypeTraits<FieldType::OLAP_FIELD_TYPE_DATEV2>::CppType;
168
    using UnsignedCppType =
169
            typename CppTypeTraits<FieldType::OLAP_FIELD_TYPE_DATEV2>::UnsignedCppType;
170
171
public:
172
8
    static void full_encode_ascending(const void* value, std::string* buf) {
173
8
        UnsignedCppType unsigned_val;
174
8
        memcpy(&unsigned_val, value, sizeof(unsigned_val));
175
        // make it bigendian
176
8
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
177
8
        buf->append((char*)&unsigned_val, sizeof(unsigned_val));
178
8
    }
179
180
0
    static void encode_ascending(const void* value, size_t index_size, std::string* buf) {
181
0
        full_encode_ascending(value, buf);
182
0
    }
183
184
0
    static Status decode_ascending(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr) {
185
0
        if (encoded_key->size < sizeof(UnsignedCppType)) {
186
0
            return Status::InvalidArgument(absl::Substitute("Key too short, need=$0 vs real=$1",
187
0
                                                            sizeof(UnsignedCppType),
188
0
                                                            encoded_key->size));
189
0
        }
190
0
        UnsignedCppType unsigned_val;
191
0
        memcpy(&unsigned_val, encoded_key->data, sizeof(UnsignedCppType));
192
0
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
193
0
        memcpy(cell_ptr, &unsigned_val, sizeof(UnsignedCppType));
194
0
        encoded_key->remove_prefix(sizeof(UnsignedCppType));
195
0
        return Status::OK();
196
0
    }
197
};
198
199
template <>
200
class KeyCoderTraits<FieldType::OLAP_FIELD_TYPE_DATETIMEV2> {
201
public:
202
    using CppType = typename CppTypeTraits<FieldType::OLAP_FIELD_TYPE_DATETIMEV2>::CppType;
203
    using UnsignedCppType =
204
            typename CppTypeTraits<FieldType::OLAP_FIELD_TYPE_DATETIMEV2>::UnsignedCppType;
205
206
public:
207
6
    static void full_encode_ascending(const void* value, std::string* buf) {
208
6
        UnsignedCppType unsigned_val;
209
6
        memcpy(&unsigned_val, value, sizeof(unsigned_val));
210
        // make it bigendian
211
6
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
212
6
        buf->append((char*)&unsigned_val, sizeof(unsigned_val));
213
6
    }
214
215
0
    static void encode_ascending(const void* value, size_t index_size, std::string* buf) {
216
0
        full_encode_ascending(value, buf);
217
0
    }
218
219
0
    static Status decode_ascending(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr) {
220
0
        if (encoded_key->size < sizeof(UnsignedCppType)) {
221
0
            return Status::InvalidArgument(absl::Substitute("Key too short, need=$0 vs real=$1",
222
0
                                                            sizeof(UnsignedCppType),
223
0
                                                            encoded_key->size));
224
0
        }
225
0
        UnsignedCppType unsigned_val;
226
0
        memcpy(&unsigned_val, encoded_key->data, sizeof(UnsignedCppType));
227
0
        unsigned_val = to_endian<std::endian::big>(unsigned_val);
228
0
        memcpy(cell_ptr, &unsigned_val, sizeof(UnsignedCppType));
229
0
        encoded_key->remove_prefix(sizeof(UnsignedCppType));
230
0
        return Status::OK();
231
0
    }
232
};
233
234
template <>
235
class KeyCoderTraits<FieldType::OLAP_FIELD_TYPE_DECIMAL> {
236
public:
237
6
    static void full_encode_ascending(const void* value, std::string* buf) {
238
6
        decimal12_t decimal_val;
239
6
        memcpy(&decimal_val, value, sizeof(decimal12_t));
240
6
        KeyCoderTraits<FieldType::OLAP_FIELD_TYPE_BIGINT>::full_encode_ascending(
241
6
                &decimal_val.integer, buf);
242
6
        KeyCoderTraits<FieldType::OLAP_FIELD_TYPE_INT>::full_encode_ascending(&decimal_val.fraction,
243
6
                                                                              buf);
244
6
    } // namespace doris
245
246
4
    static void encode_ascending(const void* value, size_t index_size, std::string* buf) {
247
4
        full_encode_ascending(value, buf);
248
4
    }
249
250
1
    static Status decode_ascending(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr) {
251
1
        decimal12_t decimal_val = {0, 0};
252
1
        RETURN_IF_ERROR(KeyCoderTraits<FieldType::OLAP_FIELD_TYPE_BIGINT>::decode_ascending(
253
1
                encoded_key, sizeof(decimal_val.integer), (uint8_t*)&decimal_val.integer));
254
1
        RETURN_IF_ERROR(KeyCoderTraits<FieldType::OLAP_FIELD_TYPE_INT>::decode_ascending(
255
1
                encoded_key, sizeof(decimal_val.fraction), (uint8_t*)&decimal_val.fraction));
256
1
        memcpy(cell_ptr, &decimal_val, sizeof(decimal12_t));
257
1
        return Status::OK();
258
1
    }
259
};
260
261
template <>
262
class KeyCoderTraits<FieldType::OLAP_FIELD_TYPE_CHAR> {
263
public:
264
2
    static void full_encode_ascending(const void* value, std::string* buf) {
265
2
        auto slice = reinterpret_cast<const Slice*>(value);
266
2
        buf->append(slice->get_data(), slice->get_size());
267
2
    }
268
269
2
    static void encode_ascending(const void* value, size_t index_size, std::string* buf) {
270
2
        const Slice* slice = (const Slice*)value;
271
2
        CHECK(index_size <= slice->size)
272
0
                << "index size is larger than char size, index=" << index_size
273
0
                << ", char=" << slice->size;
274
2
        buf->append(slice->data, index_size);
275
2
    }
276
277
0
    static Status decode_ascending(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr) {
278
0
        throw Exception(Status::FatalError("decode_ascending is not implemented"));
279
0
    }
280
};
281
282
template <>
283
class KeyCoderTraits<FieldType::OLAP_FIELD_TYPE_VARCHAR> {
284
public:
285
477
    static void full_encode_ascending(const void* value, std::string* buf) {
286
477
        auto slice = reinterpret_cast<const Slice*>(value);
287
477
        buf->append(slice->get_data(), slice->get_size());
288
477
    }
289
290
135
    static void encode_ascending(const void* value, size_t index_size, std::string* buf) {
291
135
        const Slice* slice = (const Slice*)value;
292
135
        size_t copy_size = std::min(index_size, slice->size);
293
135
        buf->append(slice->data, copy_size);
294
135
    }
295
296
0
    static Status decode_ascending(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr) {
297
0
        throw Exception(Status::FatalError("decode_ascending is not implemented"));
298
0
    }
299
};
300
301
template <>
302
class KeyCoderTraits<FieldType::OLAP_FIELD_TYPE_STRING> {
303
public:
304
884
    static void full_encode_ascending(const void* value, std::string* buf) {
305
884
        auto slice = reinterpret_cast<const Slice*>(value);
306
884
        buf->append(slice->get_data(), slice->get_size());
307
884
    }
308
309
0
    static void encode_ascending(const void* value, size_t index_size, std::string* buf) {
310
0
        const Slice* slice = (const Slice*)value;
311
0
        size_t copy_size = std::min(index_size, slice->size);
312
0
        buf->append(slice->data, copy_size);
313
0
    }
314
315
0
    static Status decode_ascending(Slice* encoded_key, size_t index_size, uint8_t* cell_ptr) {
316
0
        throw Exception(Status::FatalError("decode_ascending is not implemented"));
317
0
    }
318
};
319
320
} // namespace doris