Coverage Report

Created: 2026-07-25 15:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/util/frame_of_reference_coding.cpp
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
#include "util/frame_of_reference_coding.h"
19
20
#include <glog/logging.h>
21
#include <sys/types.h>
22
23
#include <algorithm>
24
#include <cstring>
25
#include <iostream>
26
#include <iterator>
27
#include <limits>
28
29
#include "common/cast_set.h"
30
#include "exec/common/endian.h"
31
#include "util/bit_util.h"
32
#include "util/coding.h"
33
34
namespace doris {
35
36
template <typename T>
37
8.35M
const T* ForEncoder<T>::copy_value(const T* p_data, size_t count) {
38
8.35M
    memcpy(&_buffered_values[_buffered_values_num], p_data, count * sizeof(T));
39
8.35M
    _buffered_values_num += count;
40
8.35M
    p_data += count;
41
8.35M
    return p_data;
42
8.35M
}
Unexecuted instantiation: _ZN5doris10ForEncoderIaE10copy_valueEPKam
Unexecuted instantiation: _ZN5doris10ForEncoderIsE10copy_valueEPKsm
_ZN5doris10ForEncoderIiE10copy_valueEPKim
Line
Count
Source
37
16
const T* ForEncoder<T>::copy_value(const T* p_data, size_t count) {
38
16
    memcpy(&_buffered_values[_buffered_values_num], p_data, count * sizeof(T));
39
16
    _buffered_values_num += count;
40
16
    p_data += count;
41
16
    return p_data;
42
16
}
_ZN5doris10ForEncoderIlE10copy_valueEPKlm
Line
Count
Source
37
4.17M
const T* ForEncoder<T>::copy_value(const T* p_data, size_t count) {
38
4.17M
    memcpy(&_buffered_values[_buffered_values_num], p_data, count * sizeof(T));
39
4.17M
    _buffered_values_num += count;
40
4.17M
    p_data += count;
41
4.17M
    return p_data;
42
4.17M
}
_ZN5doris10ForEncoderInE10copy_valueEPKnm
Line
Count
Source
37
4.17M
const T* ForEncoder<T>::copy_value(const T* p_data, size_t count) {
38
4.17M
    memcpy(&_buffered_values[_buffered_values_num], p_data, count * sizeof(T));
39
4.17M
    _buffered_values_num += count;
40
4.17M
    p_data += count;
41
4.17M
    return p_data;
42
4.17M
}
Unexecuted instantiation: _ZN5doris10ForEncoderIhE10copy_valueEPKhm
Unexecuted instantiation: _ZN5doris10ForEncoderItE10copy_valueEPKtm
_ZN5doris10ForEncoderIjE10copy_valueEPKjm
Line
Count
Source
37
6
const T* ForEncoder<T>::copy_value(const T* p_data, size_t count) {
38
6
    memcpy(&_buffered_values[_buffered_values_num], p_data, count * sizeof(T));
39
6
    _buffered_values_num += count;
40
6
    p_data += count;
41
6
    return p_data;
42
6
}
Unexecuted instantiation: _ZN5doris10ForEncoderImE10copy_valueEPKmm
Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE10copy_valueEPKS1_m
Unexecuted instantiation: _ZN5doris10ForEncoderIoE10copy_valueEPKom
43
44
template <typename T>
45
8.35M
void ForEncoder<T>::put_batch(const T* in_data, size_t count) {
46
8.35M
    if (_buffered_values_num + count < FRAME_VALUE_NUM) {
47
8.32M
        copy_value(in_data, count);
48
8.32M
        _values_num += count;
49
8.32M
        return;
50
8.32M
    }
51
52
    // 1. padding one frame
53
32.7k
    size_t padding_num = FRAME_VALUE_NUM - _buffered_values_num;
54
32.7k
    in_data = copy_value(in_data, padding_num);
55
32.7k
    bit_packing_one_frame_value(_buffered_values);
56
57
    // 2. process frame by frame
58
32.7k
    size_t frame_size = (count - padding_num) / FRAME_VALUE_NUM;
59
32.8k
    for (size_t i = 0; i < frame_size; i++) {
60
        // directly encode value to the bit_writer, don't buffer the value
61
16
        _buffered_values_num = FRAME_VALUE_NUM;
62
16
        bit_packing_one_frame_value(in_data);
63
16
        in_data += FRAME_VALUE_NUM;
64
16
    }
65
66
    // 3. process remaining value
67
32.7k
    size_t remaining_num = (count - padding_num) % FRAME_VALUE_NUM;
68
32.7k
    if (remaining_num > 0) {
69
8
        copy_value(in_data, remaining_num);
70
8
    }
71
72
32.7k
    _values_num += count;
73
32.7k
}
Unexecuted instantiation: _ZN5doris10ForEncoderIaE9put_batchEPKam
Unexecuted instantiation: _ZN5doris10ForEncoderIsE9put_batchEPKsm
_ZN5doris10ForEncoderIiE9put_batchEPKim
Line
Count
Source
45
14
void ForEncoder<T>::put_batch(const T* in_data, size_t count) {
46
14
    if (_buffered_values_num + count < FRAME_VALUE_NUM) {
47
8
        copy_value(in_data, count);
48
8
        _values_num += count;
49
8
        return;
50
8
    }
51
52
    // 1. padding one frame
53
6
    size_t padding_num = FRAME_VALUE_NUM - _buffered_values_num;
54
6
    in_data = copy_value(in_data, padding_num);
55
6
    bit_packing_one_frame_value(_buffered_values);
56
57
    // 2. process frame by frame
58
6
    size_t frame_size = (count - padding_num) / FRAME_VALUE_NUM;
59
10
    for (size_t i = 0; i < frame_size; i++) {
60
        // directly encode value to the bit_writer, don't buffer the value
61
4
        _buffered_values_num = FRAME_VALUE_NUM;
62
4
        bit_packing_one_frame_value(in_data);
63
4
        in_data += FRAME_VALUE_NUM;
64
4
    }
65
66
    // 3. process remaining value
67
6
    size_t remaining_num = (count - padding_num) % FRAME_VALUE_NUM;
68
6
    if (remaining_num > 0) {
69
2
        copy_value(in_data, remaining_num);
70
2
    }
71
72
6
    _values_num += count;
73
6
}
_ZN5doris10ForEncoderIlE9put_batchEPKlm
Line
Count
Source
45
4.17M
void ForEncoder<T>::put_batch(const T* in_data, size_t count) {
46
4.17M
    if (_buffered_values_num + count < FRAME_VALUE_NUM) {
47
4.16M
        copy_value(in_data, count);
48
4.16M
        _values_num += count;
49
4.16M
        return;
50
4.16M
    }
51
52
    // 1. padding one frame
53
16.3k
    size_t padding_num = FRAME_VALUE_NUM - _buffered_values_num;
54
16.3k
    in_data = copy_value(in_data, padding_num);
55
16.3k
    bit_packing_one_frame_value(_buffered_values);
56
57
    // 2. process frame by frame
58
16.3k
    size_t frame_size = (count - padding_num) / FRAME_VALUE_NUM;
59
16.3k
    for (size_t i = 0; i < frame_size; i++) {
60
        // directly encode value to the bit_writer, don't buffer the value
61
6
        _buffered_values_num = FRAME_VALUE_NUM;
62
6
        bit_packing_one_frame_value(in_data);
63
6
        in_data += FRAME_VALUE_NUM;
64
6
    }
65
66
    // 3. process remaining value
67
16.3k
    size_t remaining_num = (count - padding_num) % FRAME_VALUE_NUM;
68
16.3k
    if (remaining_num > 0) {
69
6
        copy_value(in_data, remaining_num);
70
6
    }
71
72
16.3k
    _values_num += count;
73
16.3k
}
_ZN5doris10ForEncoderInE9put_batchEPKnm
Line
Count
Source
45
4.17M
void ForEncoder<T>::put_batch(const T* in_data, size_t count) {
46
4.17M
    if (_buffered_values_num + count < FRAME_VALUE_NUM) {
47
4.16M
        copy_value(in_data, count);
48
4.16M
        _values_num += count;
49
4.16M
        return;
50
4.16M
    }
51
52
    // 1. padding one frame
53
16.3k
    size_t padding_num = FRAME_VALUE_NUM - _buffered_values_num;
54
16.3k
    in_data = copy_value(in_data, padding_num);
55
16.3k
    bit_packing_one_frame_value(_buffered_values);
56
57
    // 2. process frame by frame
58
16.3k
    size_t frame_size = (count - padding_num) / FRAME_VALUE_NUM;
59
16.3k
    for (size_t i = 0; i < frame_size; i++) {
60
        // directly encode value to the bit_writer, don't buffer the value
61
0
        _buffered_values_num = FRAME_VALUE_NUM;
62
0
        bit_packing_one_frame_value(in_data);
63
0
        in_data += FRAME_VALUE_NUM;
64
0
    }
65
66
    // 3. process remaining value
67
16.3k
    size_t remaining_num = (count - padding_num) % FRAME_VALUE_NUM;
68
16.3k
    if (remaining_num > 0) {
69
0
        copy_value(in_data, remaining_num);
70
0
    }
71
72
16.3k
    _values_num += count;
73
16.3k
}
Unexecuted instantiation: _ZN5doris10ForEncoderIhE9put_batchEPKhm
Unexecuted instantiation: _ZN5doris10ForEncoderItE9put_batchEPKtm
_ZN5doris10ForEncoderIjE9put_batchEPKjm
Line
Count
Source
45
6
void ForEncoder<T>::put_batch(const T* in_data, size_t count) {
46
6
    if (_buffered_values_num + count < FRAME_VALUE_NUM) {
47
0
        copy_value(in_data, count);
48
0
        _values_num += count;
49
0
        return;
50
0
    }
51
52
    // 1. padding one frame
53
6
    size_t padding_num = FRAME_VALUE_NUM - _buffered_values_num;
54
6
    in_data = copy_value(in_data, padding_num);
55
6
    bit_packing_one_frame_value(_buffered_values);
56
57
    // 2. process frame by frame
58
6
    size_t frame_size = (count - padding_num) / FRAME_VALUE_NUM;
59
12
    for (size_t i = 0; i < frame_size; i++) {
60
        // directly encode value to the bit_writer, don't buffer the value
61
6
        _buffered_values_num = FRAME_VALUE_NUM;
62
6
        bit_packing_one_frame_value(in_data);
63
6
        in_data += FRAME_VALUE_NUM;
64
6
    }
65
66
    // 3. process remaining value
67
6
    size_t remaining_num = (count - padding_num) % FRAME_VALUE_NUM;
68
6
    if (remaining_num > 0) {
69
0
        copy_value(in_data, remaining_num);
70
0
    }
71
72
6
    _values_num += count;
73
6
}
Unexecuted instantiation: _ZN5doris10ForEncoderImE9put_batchEPKmm
Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE9put_batchEPKS1_m
Unexecuted instantiation: _ZN5doris10ForEncoderIoE9put_batchEPKom
74
75
// todo(kks): improve this method by SIMD instructions
76
77
template <typename T>
78
30.6k
void ForEncoder<T>::bit_pack_8(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
79
30.6k
    int64_t s = 0;
80
30.6k
    uint8_t output_mask = 255;
81
30.6k
    int tail_count = in_num & 7;              // the remainder of in_num modulo 8
82
30.6k
    int full_batch_size = (in_num >> 3) << 3; // Adjust in_num to a multiple of 8
83
84
475k
    for (int i = 0; i < full_batch_size; i += 8) {
85
        // Put the 8 numbers in the input into s in order, each number occupies bit_width bit
86
445k
        s |= static_cast<int64_t>(input[i + 7]);
87
445k
        s |= (static_cast<int64_t>(input[i + 6])) << bit_width;
88
445k
        s |= (static_cast<int64_t>(input[i + 5])) << (2 * bit_width);
89
445k
        s |= (static_cast<int64_t>(input[i + 4])) << (3 * bit_width);
90
445k
        s |= (static_cast<int64_t>(input[i + 3])) << (4 * bit_width);
91
445k
        s |= (static_cast<int64_t>(input[i + 2])) << (5 * bit_width);
92
445k
        s |= (static_cast<int64_t>(input[i + 1])) << (6 * bit_width);
93
445k
        s |= (static_cast<int64_t>(input[i])) << (7 * bit_width);
94
95
        // Starting with the highest valid bit, take out 8 bits in sequence
96
        // perform an AND operation with output_mask to ensure that only 8 bits are valid
97
        // (bit_width - j - 1) << 3 used to calculate how many bits need to be removed at the end
98
2.44M
        for (int j = 0; j < bit_width; j++) {
99
2.00M
            output[j] = (s >> ((bit_width - j - 1) << 3)) & output_mask;
100
2.00M
        }
101
445k
        output += bit_width;
102
445k
        s = 0;
103
445k
    }
104
105
    // remainder
106
30.6k
    int byte = tail_count * bit_width; // How many bits are left to store
107
30.6k
    int bytes = (byte + 7) >> 3;       // How many more bytes are needed to store the rest of input
108
109
    // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit
110
130k
    for (int i = 0; i < tail_count; i++) {
111
100k
        s |= (static_cast<int64_t>(input[i + full_batch_size]))
112
100k
             << ((tail_count - i - 1) * bit_width);
113
100k
    }
114
115
    // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end
116
30.6k
    s <<= (bytes << 3) - byte;
117
118
    // Starting with the highest valid bit, take out 8 bits in sequence
119
    // perform an AND operation with output_mask to ensure that only 8 bits are valid.
120
    // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end
121
96.8k
    for (int i = 0; i < bytes; i++) {
122
66.2k
        output[i] = (s >> ((bytes - i - 1) << 3)) & output_mask;
123
66.2k
    }
124
30.6k
}
Unexecuted instantiation: _ZN5doris10ForEncoderIaE10bit_pack_8EPKahiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIsE10bit_pack_8EPKshiPh
_ZN5doris10ForEncoderIiE10bit_pack_8EPKihiPh
Line
Count
Source
78
16
void ForEncoder<T>::bit_pack_8(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
79
16
    int64_t s = 0;
80
16
    uint8_t output_mask = 255;
81
16
    int tail_count = in_num & 7;              // the remainder of in_num modulo 8
82
16
    int full_batch_size = (in_num >> 3) << 3; // Adjust in_num to a multiple of 8
83
84
208
    for (int i = 0; i < full_batch_size; i += 8) {
85
        // Put the 8 numbers in the input into s in order, each number occupies bit_width bit
86
192
        s |= static_cast<int64_t>(input[i + 7]);
87
192
        s |= (static_cast<int64_t>(input[i + 6])) << bit_width;
88
192
        s |= (static_cast<int64_t>(input[i + 5])) << (2 * bit_width);
89
192
        s |= (static_cast<int64_t>(input[i + 4])) << (3 * bit_width);
90
192
        s |= (static_cast<int64_t>(input[i + 3])) << (4 * bit_width);
91
192
        s |= (static_cast<int64_t>(input[i + 2])) << (5 * bit_width);
92
192
        s |= (static_cast<int64_t>(input[i + 1])) << (6 * bit_width);
93
192
        s |= (static_cast<int64_t>(input[i])) << (7 * bit_width);
94
95
        // Starting with the highest valid bit, take out 8 bits in sequence
96
        // perform an AND operation with output_mask to ensure that only 8 bits are valid
97
        // (bit_width - j - 1) << 3 used to calculate how many bits need to be removed at the end
98
384
        for (int j = 0; j < bit_width; j++) {
99
192
            output[j] = (s >> ((bit_width - j - 1) << 3)) & output_mask;
100
192
        }
101
192
        output += bit_width;
102
192
        s = 0;
103
192
    }
104
105
    // remainder
106
16
    int byte = tail_count * bit_width; // How many bits are left to store
107
16
    int bytes = (byte + 7) >> 3;       // How many more bytes are needed to store the rest of input
108
109
    // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit
110
20
    for (int i = 0; i < tail_count; i++) {
111
4
        s |= (static_cast<int64_t>(input[i + full_batch_size]))
112
4
             << ((tail_count - i - 1) * bit_width);
113
4
    }
114
115
    // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end
116
16
    s <<= (bytes << 3) - byte;
117
118
    // Starting with the highest valid bit, take out 8 bits in sequence
119
    // perform an AND operation with output_mask to ensure that only 8 bits are valid.
120
    // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end
121
18
    for (int i = 0; i < bytes; i++) {
122
2
        output[i] = (s >> ((bytes - i - 1) << 3)) & output_mask;
123
2
    }
124
16
}
_ZN5doris10ForEncoderIlE10bit_pack_8EPKlhiPh
Line
Count
Source
78
6.10k
void ForEncoder<T>::bit_pack_8(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
79
6.10k
    int64_t s = 0;
80
6.10k
    uint8_t output_mask = 255;
81
6.10k
    int tail_count = in_num & 7;              // the remainder of in_num modulo 8
82
6.10k
    int full_batch_size = (in_num >> 3) << 3; // Adjust in_num to a multiple of 8
83
84
69.8k
    for (int i = 0; i < full_batch_size; i += 8) {
85
        // Put the 8 numbers in the input into s in order, each number occupies bit_width bit
86
63.7k
        s |= static_cast<int64_t>(input[i + 7]);
87
63.7k
        s |= (static_cast<int64_t>(input[i + 6])) << bit_width;
88
63.7k
        s |= (static_cast<int64_t>(input[i + 5])) << (2 * bit_width);
89
63.7k
        s |= (static_cast<int64_t>(input[i + 4])) << (3 * bit_width);
90
63.7k
        s |= (static_cast<int64_t>(input[i + 3])) << (4 * bit_width);
91
63.7k
        s |= (static_cast<int64_t>(input[i + 2])) << (5 * bit_width);
92
63.7k
        s |= (static_cast<int64_t>(input[i + 1])) << (6 * bit_width);
93
63.7k
        s |= (static_cast<int64_t>(input[i])) << (7 * bit_width);
94
95
        // Starting with the highest valid bit, take out 8 bits in sequence
96
        // perform an AND operation with output_mask to ensure that only 8 bits are valid
97
        // (bit_width - j - 1) << 3 used to calculate how many bits need to be removed at the end
98
349k
        for (int j = 0; j < bit_width; j++) {
99
285k
            output[j] = (s >> ((bit_width - j - 1) << 3)) & output_mask;
100
285k
        }
101
63.7k
        output += bit_width;
102
63.7k
        s = 0;
103
63.7k
    }
104
105
    // remainder
106
6.10k
    int byte = tail_count * bit_width; // How many bits are left to store
107
6.10k
    int bytes = (byte + 7) >> 3;       // How many more bytes are needed to store the rest of input
108
109
    // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit
110
20.4k
    for (int i = 0; i < tail_count; i++) {
111
14.3k
        s |= (static_cast<int64_t>(input[i + full_batch_size]))
112
14.3k
             << ((tail_count - i - 1) * bit_width);
113
14.3k
    }
114
115
    // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end
116
6.10k
    s <<= (bytes << 3) - byte;
117
118
    // Starting with the highest valid bit, take out 8 bits in sequence
119
    // perform an AND operation with output_mask to ensure that only 8 bits are valid.
120
    // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end
121
15.5k
    for (int i = 0; i < bytes; i++) {
122
9.44k
        output[i] = (s >> ((bytes - i - 1) << 3)) & output_mask;
123
9.44k
    }
124
6.10k
}
_ZN5doris10ForEncoderInE10bit_pack_8EPKnhiPh
Line
Count
Source
78
24.4k
void ForEncoder<T>::bit_pack_8(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
79
24.4k
    int64_t s = 0;
80
24.4k
    uint8_t output_mask = 255;
81
24.4k
    int tail_count = in_num & 7;              // the remainder of in_num modulo 8
82
24.4k
    int full_batch_size = (in_num >> 3) << 3; // Adjust in_num to a multiple of 8
83
84
405k
    for (int i = 0; i < full_batch_size; i += 8) {
85
        // Put the 8 numbers in the input into s in order, each number occupies bit_width bit
86
380k
        s |= static_cast<int64_t>(input[i + 7]);
87
380k
        s |= (static_cast<int64_t>(input[i + 6])) << bit_width;
88
380k
        s |= (static_cast<int64_t>(input[i + 5])) << (2 * bit_width);
89
380k
        s |= (static_cast<int64_t>(input[i + 4])) << (3 * bit_width);
90
380k
        s |= (static_cast<int64_t>(input[i + 3])) << (4 * bit_width);
91
380k
        s |= (static_cast<int64_t>(input[i + 2])) << (5 * bit_width);
92
380k
        s |= (static_cast<int64_t>(input[i + 1])) << (6 * bit_width);
93
380k
        s |= (static_cast<int64_t>(input[i])) << (7 * bit_width);
94
95
        // Starting with the highest valid bit, take out 8 bits in sequence
96
        // perform an AND operation with output_mask to ensure that only 8 bits are valid
97
        // (bit_width - j - 1) << 3 used to calculate how many bits need to be removed at the end
98
2.09M
        for (int j = 0; j < bit_width; j++) {
99
1.71M
            output[j] = (s >> ((bit_width - j - 1) << 3)) & output_mask;
100
1.71M
        }
101
380k
        output += bit_width;
102
380k
        s = 0;
103
380k
    }
104
105
    // remainder
106
24.4k
    int byte = tail_count * bit_width; // How many bits are left to store
107
24.4k
    int bytes = (byte + 7) >> 3;       // How many more bytes are needed to store the rest of input
108
109
    // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit
110
110k
    for (int i = 0; i < tail_count; i++) {
111
86.0k
        s |= (static_cast<int64_t>(input[i + full_batch_size]))
112
86.0k
             << ((tail_count - i - 1) * bit_width);
113
86.0k
    }
114
115
    // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end
116
24.4k
    s <<= (bytes << 3) - byte;
117
118
    // Starting with the highest valid bit, take out 8 bits in sequence
119
    // perform an AND operation with output_mask to ensure that only 8 bits are valid.
120
    // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end
121
81.3k
    for (int i = 0; i < bytes; i++) {
122
56.8k
        output[i] = (s >> ((bytes - i - 1) << 3)) & output_mask;
123
56.8k
    }
124
24.4k
}
Unexecuted instantiation: _ZN5doris10ForEncoderIhE10bit_pack_8EPKhhiPh
Unexecuted instantiation: _ZN5doris10ForEncoderItE10bit_pack_8EPKthiPh
_ZN5doris10ForEncoderIjE10bit_pack_8EPKjhiPh
Line
Count
Source
78
12
void ForEncoder<T>::bit_pack_8(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
79
12
    int64_t s = 0;
80
12
    uint8_t output_mask = 255;
81
12
    int tail_count = in_num & 7;              // the remainder of in_num modulo 8
82
12
    int full_batch_size = (in_num >> 3) << 3; // Adjust in_num to a multiple of 8
83
84
204
    for (int i = 0; i < full_batch_size; i += 8) {
85
        // Put the 8 numbers in the input into s in order, each number occupies bit_width bit
86
192
        s |= static_cast<int64_t>(input[i + 7]);
87
192
        s |= (static_cast<int64_t>(input[i + 6])) << bit_width;
88
192
        s |= (static_cast<int64_t>(input[i + 5])) << (2 * bit_width);
89
192
        s |= (static_cast<int64_t>(input[i + 4])) << (3 * bit_width);
90
192
        s |= (static_cast<int64_t>(input[i + 3])) << (4 * bit_width);
91
192
        s |= (static_cast<int64_t>(input[i + 2])) << (5 * bit_width);
92
192
        s |= (static_cast<int64_t>(input[i + 1])) << (6 * bit_width);
93
192
        s |= (static_cast<int64_t>(input[i])) << (7 * bit_width);
94
95
        // Starting with the highest valid bit, take out 8 bits in sequence
96
        // perform an AND operation with output_mask to ensure that only 8 bits are valid
97
        // (bit_width - j - 1) << 3 used to calculate how many bits need to be removed at the end
98
384
        for (int j = 0; j < bit_width; j++) {
99
192
            output[j] = (s >> ((bit_width - j - 1) << 3)) & output_mask;
100
192
        }
101
192
        output += bit_width;
102
192
        s = 0;
103
192
    }
104
105
    // remainder
106
12
    int byte = tail_count * bit_width; // How many bits are left to store
107
12
    int bytes = (byte + 7) >> 3;       // How many more bytes are needed to store the rest of input
108
109
    // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit
110
12
    for (int i = 0; i < tail_count; i++) {
111
0
        s |= (static_cast<int64_t>(input[i + full_batch_size]))
112
0
             << ((tail_count - i - 1) * bit_width);
113
0
    }
114
115
    // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end
116
12
    s <<= (bytes << 3) - byte;
117
118
    // Starting with the highest valid bit, take out 8 bits in sequence
119
    // perform an AND operation with output_mask to ensure that only 8 bits are valid.
120
    // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end
121
12
    for (int i = 0; i < bytes; i++) {
122
0
        output[i] = (s >> ((bytes - i - 1) << 3)) & output_mask;
123
0
    }
124
12
}
Unexecuted instantiation: _ZN5doris10ForEncoderImE10bit_pack_8EPKmhiPh
Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE10bit_pack_8EPKS1_hiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIoE10bit_pack_8EPKohiPh
125
126
template <typename T>
127
template <typename U>
128
91.6k
void ForEncoder<T>::bit_pack_4(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
129
91.6k
    U s = 0;
130
91.6k
    uint8_t output_mask = 255;
131
91.6k
    int tail_count = in_num & 3;              // the remainder of in_num modulo 4
132
91.6k
    int full_batch_size = (in_num >> 2) << 2; // Adjust in_num to a multiple of 4
133
91.6k
    int output_size = 0;                      // How many outputs can be processed at a time
134
91.6k
    int bit_width_remainder =
135
91.6k
            (bit_width << 2) & 7; // How many bits will be left after processing 4 numbers at a time
136
91.6k
    int extra_bit = 0;            // Extra bits after each process
137
138
2.80M
    for (int i = 0; i < full_batch_size; i += 4) {
139
        // Put the 4 numbers in the input into s in order, each number occupies bit_width bit
140
        // The reason for using s<<=bit_width first is that there are unprocessed bits in the previous loop
141
2.70M
        s <<= bit_width;
142
2.70M
        s |= (static_cast<U>(input[i]));
143
2.70M
        s <<= bit_width;
144
2.70M
        s |= (static_cast<U>(input[i + 1]));
145
2.70M
        s <<= bit_width;
146
2.70M
        s |= (static_cast<U>(input[i + 2]));
147
2.70M
        s <<= bit_width;
148
2.70M
        s |= (static_cast<U>(input[i + 3]));
149
150
        // ((bit_width * 4) + extra_bit) / 8: There are bit_width*4 bits to be processed in s,
151
        // and there are extra_bit bits left over from the last loop,
152
        // divide by 8 to calculate how much output can be processed in this loop.
153
2.70M
        output_size = ((bit_width << 2) + extra_bit) >> 3;
154
155
        // Each loop will leave bit_width_remainder bit unprocessed,
156
        // last loop will leave extra_bit bit, eventually will leave
157
        // (extra_bit + bit_width_remainder) & 7 bit unprocessed
158
2.70M
        extra_bit = (extra_bit + bit_width_remainder) & 7;
159
160
        // Starting with the highest valid bit, take out 8 bits in sequence
161
        // perform an AND operation with output_mask to ensure that only 8 bits are valid
162
        // (output_size-j-1)<<3 used to calculate how many bits need to be removed at the end
163
        // But since there are still extra_bit bits that can't be processed, need to add the extra_bit
164
30.4M
        for (int j = 0; j < output_size; j++) {
165
27.7M
            output[j] = (s >> (((output_size - j - 1) << 3) + extra_bit)) & output_mask;
166
27.7M
        }
167
2.70M
        output += output_size;
168
169
        // s retains the post extra_bit bit as it is not processed
170
2.70M
        s &= (1 << extra_bit) - 1;
171
2.70M
    }
172
173
    // remainder
174
91.6k
    int byte = tail_count * bit_width;     // How many bits are left to store
175
91.6k
    if (extra_bit != 0) byte += extra_bit; // add extra_bit bit as it is not processed
176
91.6k
    int bytes = (byte + 7) >> 3; // How many more bytes are needed to store the rest of input
177
178
    // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit
179
220k
    for (int i = 0; i < tail_count; i++) {
180
128k
        s <<= bit_width;
181
128k
        s |= (input[i + full_batch_size]);
182
128k
    }
183
184
    // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end
185
91.6k
    s <<= (bytes << 3) - byte;
186
187
    // Starting with the highest valid bit, take out 8 bits in sequence
188
    // perform an AND operation with output_mask to ensure that only 8 bits are valid.
189
    // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end
190
462k
    for (int i = 0; i < bytes; i++) {
191
370k
        output[i] = (s >> (((bytes - i - 1) << 3))) & output_mask;
192
370k
    }
193
91.6k
}
Unexecuted instantiation: _ZN5doris10ForEncoderIaE10bit_pack_4IlEEvPKahiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIaE10bit_pack_4InEEvPKahiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIsE10bit_pack_4IlEEvPKshiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIsE10bit_pack_4InEEvPKshiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIiE10bit_pack_4IlEEvPKihiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIiE10bit_pack_4InEEvPKihiPh
_ZN5doris10ForEncoderIlE10bit_pack_4IlEEvPKlhiPh
Line
Count
Source
128
6.07k
void ForEncoder<T>::bit_pack_4(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
129
6.07k
    U s = 0;
130
6.07k
    uint8_t output_mask = 255;
131
6.07k
    int tail_count = in_num & 3;              // the remainder of in_num modulo 4
132
6.07k
    int full_batch_size = (in_num >> 2) << 2; // Adjust in_num to a multiple of 4
133
6.07k
    int output_size = 0;                      // How many outputs can be processed at a time
134
6.07k
    int bit_width_remainder =
135
6.07k
            (bit_width << 2) & 7; // How many bits will be left after processing 4 numbers at a time
136
6.07k
    int extra_bit = 0;            // Extra bits after each process
137
138
135k
    for (int i = 0; i < full_batch_size; i += 4) {
139
        // Put the 4 numbers in the input into s in order, each number occupies bit_width bit
140
        // The reason for using s<<=bit_width first is that there are unprocessed bits in the previous loop
141
129k
        s <<= bit_width;
142
129k
        s |= (static_cast<U>(input[i]));
143
129k
        s <<= bit_width;
144
129k
        s |= (static_cast<U>(input[i + 1]));
145
129k
        s <<= bit_width;
146
129k
        s |= (static_cast<U>(input[i + 2]));
147
129k
        s <<= bit_width;
148
129k
        s |= (static_cast<U>(input[i + 3]));
149
150
        // ((bit_width * 4) + extra_bit) / 8: There are bit_width*4 bits to be processed in s,
151
        // and there are extra_bit bits left over from the last loop,
152
        // divide by 8 to calculate how much output can be processed in this loop.
153
129k
        output_size = ((bit_width << 2) + extra_bit) >> 3;
154
155
        // Each loop will leave bit_width_remainder bit unprocessed,
156
        // last loop will leave extra_bit bit, eventually will leave
157
        // (extra_bit + bit_width_remainder) & 7 bit unprocessed
158
129k
        extra_bit = (extra_bit + bit_width_remainder) & 7;
159
160
        // Starting with the highest valid bit, take out 8 bits in sequence
161
        // perform an AND operation with output_mask to ensure that only 8 bits are valid
162
        // (output_size-j-1)<<3 used to calculate how many bits need to be removed at the end
163
        // But since there are still extra_bit bits that can't be processed, need to add the extra_bit
164
934k
        for (int j = 0; j < output_size; j++) {
165
805k
            output[j] = (s >> (((output_size - j - 1) << 3) + extra_bit)) & output_mask;
166
805k
        }
167
129k
        output += output_size;
168
169
        // s retains the post extra_bit bit as it is not processed
170
129k
        s &= (1 << extra_bit) - 1;
171
129k
    }
172
173
    // remainder
174
6.07k
    int byte = tail_count * bit_width;     // How many bits are left to store
175
6.07k
    if (extra_bit != 0) byte += extra_bit; // add extra_bit bit as it is not processed
176
6.07k
    int bytes = (byte + 7) >> 3; // How many more bytes are needed to store the rest of input
177
178
    // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit
179
12.1k
    for (int i = 0; i < tail_count; i++) {
180
6.09k
        s <<= bit_width;
181
6.09k
        s |= (input[i + full_batch_size]);
182
6.09k
    }
183
184
    // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end
185
6.07k
    s <<= (bytes << 3) - byte;
186
187
    // Starting with the highest valid bit, take out 8 bits in sequence
188
    // perform an AND operation with output_mask to ensure that only 8 bits are valid.
189
    // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end
190
17.5k
    for (int i = 0; i < bytes; i++) {
191
11.4k
        output[i] = (s >> (((bytes - i - 1) << 3))) & output_mask;
192
11.4k
    }
193
6.07k
}
_ZN5doris10ForEncoderIlE10bit_pack_4InEEvPKlhiPh
Line
Count
Source
128
12.1k
void ForEncoder<T>::bit_pack_4(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
129
12.1k
    U s = 0;
130
12.1k
    uint8_t output_mask = 255;
131
12.1k
    int tail_count = in_num & 3;              // the remainder of in_num modulo 4
132
12.1k
    int full_batch_size = (in_num >> 2) << 2; // Adjust in_num to a multiple of 4
133
12.1k
    int output_size = 0;                      // How many outputs can be processed at a time
134
12.1k
    int bit_width_remainder =
135
12.1k
            (bit_width << 2) & 7; // How many bits will be left after processing 4 numbers at a time
136
12.1k
    int extra_bit = 0;            // Extra bits after each process
137
138
270k
    for (int i = 0; i < full_batch_size; i += 4) {
139
        // Put the 4 numbers in the input into s in order, each number occupies bit_width bit
140
        // The reason for using s<<=bit_width first is that there are unprocessed bits in the previous loop
141
258k
        s <<= bit_width;
142
258k
        s |= (static_cast<U>(input[i]));
143
258k
        s <<= bit_width;
144
258k
        s |= (static_cast<U>(input[i + 1]));
145
258k
        s <<= bit_width;
146
258k
        s |= (static_cast<U>(input[i + 2]));
147
258k
        s <<= bit_width;
148
258k
        s |= (static_cast<U>(input[i + 3]));
149
150
        // ((bit_width * 4) + extra_bit) / 8: There are bit_width*4 bits to be processed in s,
151
        // and there are extra_bit bits left over from the last loop,
152
        // divide by 8 to calculate how much output can be processed in this loop.
153
258k
        output_size = ((bit_width << 2) + extra_bit) >> 3;
154
155
        // Each loop will leave bit_width_remainder bit unprocessed,
156
        // last loop will leave extra_bit bit, eventually will leave
157
        // (extra_bit + bit_width_remainder) & 7 bit unprocessed
158
258k
        extra_bit = (extra_bit + bit_width_remainder) & 7;
159
160
        // Starting with the highest valid bit, take out 8 bits in sequence
161
        // perform an AND operation with output_mask to ensure that only 8 bits are valid
162
        // (output_size-j-1)<<3 used to calculate how many bits need to be removed at the end
163
        // But since there are still extra_bit bits that can't be processed, need to add the extra_bit
164
3.41M
        for (int j = 0; j < output_size; j++) {
165
3.16M
            output[j] = (s >> (((output_size - j - 1) << 3) + extra_bit)) & output_mask;
166
3.16M
        }
167
258k
        output += output_size;
168
169
        // s retains the post extra_bit bit as it is not processed
170
258k
        s &= (1 << extra_bit) - 1;
171
258k
    }
172
173
    // remainder
174
12.1k
    int byte = tail_count * bit_width;     // How many bits are left to store
175
12.1k
    if (extra_bit != 0) byte += extra_bit; // add extra_bit bit as it is not processed
176
12.1k
    int bytes = (byte + 7) >> 3; // How many more bytes are needed to store the rest of input
177
178
    // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit
179
24.4k
    for (int i = 0; i < tail_count; i++) {
180
12.2k
        s <<= bit_width;
181
12.2k
        s |= (input[i + full_batch_size]);
182
12.2k
    }
183
184
    // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end
185
12.1k
    s <<= (bytes << 3) - byte;
186
187
    // Starting with the highest valid bit, take out 8 bits in sequence
188
    // perform an AND operation with output_mask to ensure that only 8 bits are valid.
189
    // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end
190
53.4k
    for (int i = 0; i < bytes; i++) {
191
41.3k
        output[i] = (s >> (((bytes - i - 1) << 3))) & output_mask;
192
41.3k
    }
193
12.1k
}
_ZN5doris10ForEncoderInE10bit_pack_4IlEEvPKnhiPh
Line
Count
Source
128
24.4k
void ForEncoder<T>::bit_pack_4(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
129
24.4k
    U s = 0;
130
24.4k
    uint8_t output_mask = 255;
131
24.4k
    int tail_count = in_num & 3;              // the remainder of in_num modulo 4
132
24.4k
    int full_batch_size = (in_num >> 2) << 2; // Adjust in_num to a multiple of 4
133
24.4k
    int output_size = 0;                      // How many outputs can be processed at a time
134
24.4k
    int bit_width_remainder =
135
24.4k
            (bit_width << 2) & 7; // How many bits will be left after processing 4 numbers at a time
136
24.4k
    int extra_bit = 0;            // Extra bits after each process
137
138
798k
    for (int i = 0; i < full_batch_size; i += 4) {
139
        // Put the 4 numbers in the input into s in order, each number occupies bit_width bit
140
        // The reason for using s<<=bit_width first is that there are unprocessed bits in the previous loop
141
774k
        s <<= bit_width;
142
774k
        s |= (static_cast<U>(input[i]));
143
774k
        s <<= bit_width;
144
774k
        s |= (static_cast<U>(input[i + 1]));
145
774k
        s <<= bit_width;
146
774k
        s |= (static_cast<U>(input[i + 2]));
147
774k
        s <<= bit_width;
148
774k
        s |= (static_cast<U>(input[i + 3]));
149
150
        // ((bit_width * 4) + extra_bit) / 8: There are bit_width*4 bits to be processed in s,
151
        // and there are extra_bit bits left over from the last loop,
152
        // divide by 8 to calculate how much output can be processed in this loop.
153
774k
        output_size = ((bit_width << 2) + extra_bit) >> 3;
154
155
        // Each loop will leave bit_width_remainder bit unprocessed,
156
        // last loop will leave extra_bit bit, eventually will leave
157
        // (extra_bit + bit_width_remainder) & 7 bit unprocessed
158
774k
        extra_bit = (extra_bit + bit_width_remainder) & 7;
159
160
        // Starting with the highest valid bit, take out 8 bits in sequence
161
        // perform an AND operation with output_mask to ensure that only 8 bits are valid
162
        // (output_size-j-1)<<3 used to calculate how many bits need to be removed at the end
163
        // But since there are still extra_bit bits that can't be processed, need to add the extra_bit
164
5.60M
        for (int j = 0; j < output_size; j++) {
165
4.83M
            output[j] = (s >> (((output_size - j - 1) << 3) + extra_bit)) & output_mask;
166
4.83M
        }
167
774k
        output += output_size;
168
169
        // s retains the post extra_bit bit as it is not processed
170
774k
        s &= (1 << extra_bit) - 1;
171
774k
    }
172
173
    // remainder
174
24.4k
    int byte = tail_count * bit_width;     // How many bits are left to store
175
24.4k
    if (extra_bit != 0) byte += extra_bit; // add extra_bit bit as it is not processed
176
24.4k
    int bytes = (byte + 7) >> 3; // How many more bytes are needed to store the rest of input
177
178
    // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit
179
61.3k
    for (int i = 0; i < tail_count; i++) {
180
36.8k
        s <<= bit_width;
181
36.8k
        s |= (input[i + full_batch_size]);
182
36.8k
    }
183
184
    // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end
185
24.4k
    s <<= (bytes << 3) - byte;
186
187
    // Starting with the highest valid bit, take out 8 bits in sequence
188
    // perform an AND operation with output_mask to ensure that only 8 bits are valid.
189
    // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end
190
93.6k
    for (int i = 0; i < bytes; i++) {
191
69.1k
        output[i] = (s >> (((bytes - i - 1) << 3))) & output_mask;
192
69.1k
    }
193
24.4k
}
_ZN5doris10ForEncoderInE10bit_pack_4InEEvPKnhiPh
Line
Count
Source
128
48.9k
void ForEncoder<T>::bit_pack_4(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
129
48.9k
    U s = 0;
130
48.9k
    uint8_t output_mask = 255;
131
48.9k
    int tail_count = in_num & 3;              // the remainder of in_num modulo 4
132
48.9k
    int full_batch_size = (in_num >> 2) << 2; // Adjust in_num to a multiple of 4
133
48.9k
    int output_size = 0;                      // How many outputs can be processed at a time
134
48.9k
    int bit_width_remainder =
135
48.9k
            (bit_width << 2) & 7; // How many bits will be left after processing 4 numbers at a time
136
48.9k
    int extra_bit = 0;            // Extra bits after each process
137
138
1.59M
    for (int i = 0; i < full_batch_size; i += 4) {
139
        // Put the 4 numbers in the input into s in order, each number occupies bit_width bit
140
        // The reason for using s<<=bit_width first is that there are unprocessed bits in the previous loop
141
1.54M
        s <<= bit_width;
142
1.54M
        s |= (static_cast<U>(input[i]));
143
1.54M
        s <<= bit_width;
144
1.54M
        s |= (static_cast<U>(input[i + 1]));
145
1.54M
        s <<= bit_width;
146
1.54M
        s |= (static_cast<U>(input[i + 2]));
147
1.54M
        s <<= bit_width;
148
1.54M
        s |= (static_cast<U>(input[i + 3]));
149
150
        // ((bit_width * 4) + extra_bit) / 8: There are bit_width*4 bits to be processed in s,
151
        // and there are extra_bit bits left over from the last loop,
152
        // divide by 8 to calculate how much output can be processed in this loop.
153
1.54M
        output_size = ((bit_width << 2) + extra_bit) >> 3;
154
155
        // Each loop will leave bit_width_remainder bit unprocessed,
156
        // last loop will leave extra_bit bit, eventually will leave
157
        // (extra_bit + bit_width_remainder) & 7 bit unprocessed
158
1.54M
        extra_bit = (extra_bit + bit_width_remainder) & 7;
159
160
        // Starting with the highest valid bit, take out 8 bits in sequence
161
        // perform an AND operation with output_mask to ensure that only 8 bits are valid
162
        // (output_size-j-1)<<3 used to calculate how many bits need to be removed at the end
163
        // But since there are still extra_bit bits that can't be processed, need to add the extra_bit
164
20.5M
        for (int j = 0; j < output_size; j++) {
165
18.9M
            output[j] = (s >> (((output_size - j - 1) << 3) + extra_bit)) & output_mask;
166
18.9M
        }
167
1.54M
        output += output_size;
168
169
        // s retains the post extra_bit bit as it is not processed
170
1.54M
        s &= (1 << extra_bit) - 1;
171
1.54M
    }
172
173
    // remainder
174
48.9k
    int byte = tail_count * bit_width;     // How many bits are left to store
175
48.9k
    if (extra_bit != 0) byte += extra_bit; // add extra_bit bit as it is not processed
176
48.9k
    int bytes = (byte + 7) >> 3; // How many more bytes are needed to store the rest of input
177
178
    // Put the tail_count numbers in the input into s in order, each number occupies bit_width bit
179
122k
    for (int i = 0; i < tail_count; i++) {
180
73.7k
        s <<= bit_width;
181
73.7k
        s |= (input[i + full_batch_size]);
182
73.7k
    }
183
184
    // If byte is not a multiple of 8 and therefore needs to be padded with 0 at the end
185
48.9k
    s <<= (bytes << 3) - byte;
186
187
    // Starting with the highest valid bit, take out 8 bits in sequence
188
    // perform an AND operation with output_mask to ensure that only 8 bits are valid.
189
    // (bytes - i - 1) << 3 used to calculate how many bits need to be removed at the end
190
297k
    for (int i = 0; i < bytes; i++) {
191
248k
        output[i] = (s >> (((bytes - i - 1) << 3))) & output_mask;
192
248k
    }
193
48.9k
}
Unexecuted instantiation: _ZN5doris10ForEncoderIhE10bit_pack_4IlEEvPKhhiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIhE10bit_pack_4InEEvPKhhiPh
Unexecuted instantiation: _ZN5doris10ForEncoderItE10bit_pack_4IlEEvPKthiPh
Unexecuted instantiation: _ZN5doris10ForEncoderItE10bit_pack_4InEEvPKthiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIjE10bit_pack_4IlEEvPKjhiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIjE10bit_pack_4InEEvPKjhiPh
Unexecuted instantiation: _ZN5doris10ForEncoderImE10bit_pack_4IlEEvPKmhiPh
Unexecuted instantiation: _ZN5doris10ForEncoderImE10bit_pack_4InEEvPKmhiPh
Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE10bit_pack_4IlEEvPKS1_hiPh
Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE10bit_pack_4InEEvPKS1_hiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIoE10bit_pack_4IlEEvPKohiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIoE10bit_pack_4InEEvPKohiPh
194
195
template <typename T>
196
363k
void ForEncoder<T>::bit_pack_1(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
197
363k
    int output_mask = 255;
198
363k
    int need_bit = 0; // still need
199
200
43.8M
    for (int i = 0; i < in_num; i++) {
201
43.4M
        T x = input[i];
202
43.4M
        int width = bit_width;
203
43.4M
        if (need_bit) {
204
            // The last time we take away the high 8 - need_bit,
205
            // we need to make up the rest of the need_bit from the width.
206
            // Use width - need_bit to compute high need_bit bits
207
30.0M
            *output |= x >> (width - need_bit);
208
30.0M
            output++;
209
            // There are need_bit bits being used, so subtract
210
30.0M
            width -= need_bit;
211
30.0M
        }
212
43.4M
        int num = width >> 3;      // How many outputs can be processed at a time
213
43.4M
        int remainder = width & 7; // How many bits are left to store
214
215
        // Starting with the highest valid bit, take out 8 bits in sequence
216
        // perform an AND operation with output_mask to ensure that only 8 bits are valid
217
        // (num-j-1)<<3 used to calculate how many bits need to be removed at the end
218
        // But since there are still remainder bits that can't be processed, need to add the remainder
219
447M
        for (int j = 0; j < num; j++) {
220
404M
            *output = cast_set<uint8_t>((x >> (((num - j - 1) << 3) + remainder)) & output_mask);
221
404M
            output++;
222
404M
        }
223
43.4M
        if (remainder) {
224
            // Process the last remaining remainder bit.
225
            // y = (x & ((1 << remainder) - 1)) extract the last remainder bits.
226
            // ouput = y << (8 - reaminder)  Use the high 8 - remainder bit
227
30.3M
            *output = cast_set<uint8_t>((x & ((1 << remainder) - 1)) << (8 - remainder));
228
            // Already have remainder bits, next time need 8-remainder bits
229
30.3M
            need_bit = 8 - remainder;
230
30.3M
        } else {
231
13.1M
            need_bit = 0;
232
13.1M
        }
233
43.4M
    }
234
363k
}
Unexecuted instantiation: _ZN5doris10ForEncoderIaE10bit_pack_1EPKahiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIsE10bit_pack_1EPKshiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIiE10bit_pack_1EPKihiPh
_ZN5doris10ForEncoderIlE10bit_pack_1EPKlhiPh
Line
Count
Source
196
24.3k
void ForEncoder<T>::bit_pack_1(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
197
24.3k
    int output_mask = 255;
198
24.3k
    int need_bit = 0; // still need
199
200
2.11M
    for (int i = 0; i < in_num; i++) {
201
2.08M
        T x = input[i];
202
2.08M
        int width = bit_width;
203
2.08M
        if (need_bit) {
204
            // The last time we take away the high 8 - need_bit,
205
            // we need to make up the rest of the need_bit from the width.
206
            // Use width - need_bit to compute high need_bit bits
207
1.48M
            *output |= x >> (width - need_bit);
208
1.48M
            output++;
209
            // There are need_bit bits being used, so subtract
210
1.48M
            width -= need_bit;
211
1.48M
        }
212
2.08M
        int num = width >> 3;      // How many outputs can be processed at a time
213
2.08M
        int remainder = width & 7; // How many bits are left to store
214
215
        // Starting with the highest valid bit, take out 8 bits in sequence
216
        // perform an AND operation with output_mask to ensure that only 8 bits are valid
217
        // (num-j-1)<<3 used to calculate how many bits need to be removed at the end
218
        // But since there are still remainder bits that can't be processed, need to add the remainder
219
13.2M
        for (int j = 0; j < num; j++) {
220
11.1M
            *output = cast_set<uint8_t>((x >> (((num - j - 1) << 3) + remainder)) & output_mask);
221
11.1M
            output++;
222
11.1M
        }
223
2.08M
        if (remainder) {
224
            // Process the last remaining remainder bit.
225
            // y = (x & ((1 << remainder) - 1)) extract the last remainder bits.
226
            // ouput = y << (8 - reaminder)  Use the high 8 - remainder bit
227
1.49M
            *output = cast_set<uint8_t>((x & ((1 << remainder) - 1)) << (8 - remainder));
228
            // Already have remainder bits, next time need 8-remainder bits
229
1.49M
            need_bit = 8 - remainder;
230
1.49M
        } else {
231
589k
            need_bit = 0;
232
589k
        }
233
2.08M
    }
234
24.3k
}
_ZN5doris10ForEncoderInE10bit_pack_1EPKnhiPh
Line
Count
Source
196
339k
void ForEncoder<T>::bit_pack_1(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
197
339k
    int output_mask = 255;
198
339k
    int need_bit = 0; // still need
199
200
41.7M
    for (int i = 0; i < in_num; i++) {
201
41.3M
        T x = input[i];
202
41.3M
        int width = bit_width;
203
41.3M
        if (need_bit) {
204
            // The last time we take away the high 8 - need_bit,
205
            // we need to make up the rest of the need_bit from the width.
206
            // Use width - need_bit to compute high need_bit bits
207
28.6M
            *output |= x >> (width - need_bit);
208
28.6M
            output++;
209
            // There are need_bit bits being used, so subtract
210
28.6M
            width -= need_bit;
211
28.6M
        }
212
41.3M
        int num = width >> 3;      // How many outputs can be processed at a time
213
41.3M
        int remainder = width & 7; // How many bits are left to store
214
215
        // Starting with the highest valid bit, take out 8 bits in sequence
216
        // perform an AND operation with output_mask to ensure that only 8 bits are valid
217
        // (num-j-1)<<3 used to calculate how many bits need to be removed at the end
218
        // But since there are still remainder bits that can't be processed, need to add the remainder
219
434M
        for (int j = 0; j < num; j++) {
220
393M
            *output = cast_set<uint8_t>((x >> (((num - j - 1) << 3) + remainder)) & output_mask);
221
393M
            output++;
222
393M
        }
223
41.3M
        if (remainder) {
224
            // Process the last remaining remainder bit.
225
            // y = (x & ((1 << remainder) - 1)) extract the last remainder bits.
226
            // ouput = y << (8 - reaminder)  Use the high 8 - remainder bit
227
28.8M
            *output = cast_set<uint8_t>((x & ((1 << remainder) - 1)) << (8 - remainder));
228
            // Already have remainder bits, next time need 8-remainder bits
229
28.8M
            need_bit = 8 - remainder;
230
28.8M
        } else {
231
12.5M
            need_bit = 0;
232
12.5M
        }
233
41.3M
    }
234
339k
}
Unexecuted instantiation: _ZN5doris10ForEncoderIhE10bit_pack_1EPKhhiPh
Unexecuted instantiation: _ZN5doris10ForEncoderItE10bit_pack_1EPKthiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIjE10bit_pack_1EPKjhiPh
Unexecuted instantiation: _ZN5doris10ForEncoderImE10bit_pack_1EPKmhiPh
Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE10bit_pack_1EPKS1_hiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIoE10bit_pack_1EPKohiPh
235
236
// Use as few bit as possible to store a piece of integer data.
237
// param[in] input: the integer list need to pack
238
// param[in] in_num: the number integer need to pack
239
// param[in] bit_width: how many bit we use to store each integer data
240
// param[out] out: the packed result
241
242
// For example:
243
// The input is int32 list: 1, 2, 4, 8 and bit_width is 4
244
// The output will be: 0001 0010 0100 1000
245
template <typename T>
246
486k
void ForEncoder<T>::bit_pack(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
247
486k
    if (in_num == 0 || bit_width == 0) {
248
520
        return;
249
520
    }
250
    /*
251
        bit_width <= 8 : pack_8 > pack_16 > pack_32
252
        bit_width <= 16 : pack_4 > pack_8 > pack_16
253
        bit_width <= 32 : pack_4 >= pack_2 > pack_8 
254
        (pack_4 and pack_2 have nearly similar execution times, but pack_4 utilizes space more efficiently)
255
        bit_width <= 64 : pack_1 > pack_4
256
    */
257
485k
    if (bit_width <= 8) {
258
30.6k
        bit_pack_8(input, in_num, bit_width, output);
259
455k
    } else if (bit_width <= 16) {
260
30.5k
        bit_pack_4<int64_t>(input, in_num, bit_width, output);
261
424k
    } else if (bit_width <= 32) {
262
61.1k
        bit_pack_4<__int128_t>(input, in_num, bit_width, output);
263
363k
    } else {
264
363k
        bit_pack_1(input, in_num, bit_width, output);
265
363k
    }
266
485k
}
Unexecuted instantiation: _ZN5doris10ForEncoderIaE8bit_packEPKahiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIsE8bit_packEPKshiPh
_ZN5doris10ForEncoderIiE8bit_packEPKihiPh
Line
Count
Source
246
18
void ForEncoder<T>::bit_pack(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
247
18
    if (in_num == 0 || bit_width == 0) {
248
2
        return;
249
2
    }
250
    /*
251
        bit_width <= 8 : pack_8 > pack_16 > pack_32
252
        bit_width <= 16 : pack_4 > pack_8 > pack_16
253
        bit_width <= 32 : pack_4 >= pack_2 > pack_8 
254
        (pack_4 and pack_2 have nearly similar execution times, but pack_4 utilizes space more efficiently)
255
        bit_width <= 64 : pack_1 > pack_4
256
    */
257
16
    if (bit_width <= 8) {
258
16
        bit_pack_8(input, in_num, bit_width, output);
259
16
    } else if (bit_width <= 16) {
260
0
        bit_pack_4<int64_t>(input, in_num, bit_width, output);
261
0
    } else if (bit_width <= 32) {
262
0
        bit_pack_4<__int128_t>(input, in_num, bit_width, output);
263
0
    } else {
264
0
        bit_pack_1(input, in_num, bit_width, output);
265
0
    }
266
16
}
_ZN5doris10ForEncoderIlE8bit_packEPKlhiPh
Line
Count
Source
246
48.9k
void ForEncoder<T>::bit_pack(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
247
48.9k
    if (in_num == 0 || bit_width == 0) {
248
262
        return;
249
262
    }
250
    /*
251
        bit_width <= 8 : pack_8 > pack_16 > pack_32
252
        bit_width <= 16 : pack_4 > pack_8 > pack_16
253
        bit_width <= 32 : pack_4 >= pack_2 > pack_8 
254
        (pack_4 and pack_2 have nearly similar execution times, but pack_4 utilizes space more efficiently)
255
        bit_width <= 64 : pack_1 > pack_4
256
    */
257
48.6k
    if (bit_width <= 8) {
258
6.10k
        bit_pack_8(input, in_num, bit_width, output);
259
42.5k
    } else if (bit_width <= 16) {
260
6.07k
        bit_pack_4<int64_t>(input, in_num, bit_width, output);
261
36.4k
    } else if (bit_width <= 32) {
262
12.1k
        bit_pack_4<__int128_t>(input, in_num, bit_width, output);
263
24.3k
    } else {
264
24.3k
        bit_pack_1(input, in_num, bit_width, output);
265
24.3k
    }
266
48.6k
}
_ZN5doris10ForEncoderInE8bit_packEPKnhiPh
Line
Count
Source
246
437k
void ForEncoder<T>::bit_pack(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
247
437k
    if (in_num == 0 || bit_width == 0) {
248
256
        return;
249
256
    }
250
    /*
251
        bit_width <= 8 : pack_8 > pack_16 > pack_32
252
        bit_width <= 16 : pack_4 > pack_8 > pack_16
253
        bit_width <= 32 : pack_4 >= pack_2 > pack_8 
254
        (pack_4 and pack_2 have nearly similar execution times, but pack_4 utilizes space more efficiently)
255
        bit_width <= 64 : pack_1 > pack_4
256
    */
257
437k
    if (bit_width <= 8) {
258
24.4k
        bit_pack_8(input, in_num, bit_width, output);
259
412k
    } else if (bit_width <= 16) {
260
24.4k
        bit_pack_4<int64_t>(input, in_num, bit_width, output);
261
388k
    } else if (bit_width <= 32) {
262
48.9k
        bit_pack_4<__int128_t>(input, in_num, bit_width, output);
263
339k
    } else {
264
339k
        bit_pack_1(input, in_num, bit_width, output);
265
339k
    }
266
437k
}
Unexecuted instantiation: _ZN5doris10ForEncoderIhE8bit_packEPKhhiPh
Unexecuted instantiation: _ZN5doris10ForEncoderItE8bit_packEPKthiPh
_ZN5doris10ForEncoderIjE8bit_packEPKjhiPh
Line
Count
Source
246
12
void ForEncoder<T>::bit_pack(const T* input, uint8_t in_num, int bit_width, uint8_t* output) {
247
12
    if (in_num == 0 || bit_width == 0) {
248
0
        return;
249
0
    }
250
    /*
251
        bit_width <= 8 : pack_8 > pack_16 > pack_32
252
        bit_width <= 16 : pack_4 > pack_8 > pack_16
253
        bit_width <= 32 : pack_4 >= pack_2 > pack_8 
254
        (pack_4 and pack_2 have nearly similar execution times, but pack_4 utilizes space more efficiently)
255
        bit_width <= 64 : pack_1 > pack_4
256
    */
257
12
    if (bit_width <= 8) {
258
12
        bit_pack_8(input, in_num, bit_width, output);
259
12
    } else if (bit_width <= 16) {
260
0
        bit_pack_4<int64_t>(input, in_num, bit_width, output);
261
0
    } else if (bit_width <= 32) {
262
0
        bit_pack_4<__int128_t>(input, in_num, bit_width, output);
263
0
    } else {
264
0
        bit_pack_1(input, in_num, bit_width, output);
265
0
    }
266
12
}
Unexecuted instantiation: _ZN5doris10ForEncoderImE8bit_packEPKmhiPh
Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE8bit_packEPKS1_hiPh
Unexecuted instantiation: _ZN5doris10ForEncoderIoE8bit_packEPKohiPh
267
268
template <typename T>
269
97.8k
void ForEncoder<T>::bit_packing_one_frame_value(const T* input) {
270
97.8k
    T min = input[0];
271
97.8k
    T max = input[0];
272
97.8k
    bool is_ascending = true;
273
97.8k
    uint8_t bit_width = 0;
274
97.8k
    T half_max_delta = numeric_limits_max() >> 1;
275
97.8k
    bool is_keep_original_value = false;
276
277
    // 1. make sure order_flag, save_original_value, and find max&min.
278
8.36M
    for (uint8_t i = 1; i < _buffered_values_num; ++i) {
279
8.26M
        if (is_ascending) {
280
172k
            if (input[i] < input[i - 1]) {
281
96.9k
                is_ascending = false;
282
96.9k
            } else {
283
76.0k
                if ((input[i] >> 1) - (input[i - 1] >> 1) > half_max_delta) { // overflow
284
0
                    is_keep_original_value = true;
285
76.0k
                } else {
286
76.0k
                    bit_width = std::max(bit_width, bits(input[i] - input[i - 1]));
287
76.0k
                }
288
76.0k
            }
289
172k
        }
290
291
8.26M
        if (input[i] < min) {
292
361k
            min = input[i];
293
361k
            continue;
294
361k
        }
295
296
7.90M
        if (input[i] > max) {
297
367k
            max = input[i];
298
367k
        }
299
7.90M
    }
300
97.8k
    if (!is_ascending) {
301
96.9k
        if ((max >> 1) - (min >> 1) > half_max_delta) {
302
0
            is_keep_original_value = true;
303
0
        }
304
96.9k
    }
305
306
    // 2. save min value.
307
97.8k
    if (sizeof(T) == 16) {
308
48.8k
        put_fixed128_le(_buffer, static_cast<uint128_t>(min));
309
48.9k
    } else if (sizeof(T) == 8) {
310
48.9k
        put_fixed64_le(_buffer, static_cast<uint64_t>(min));
311
48.9k
    } else {
312
30
        put_fixed32_le(_buffer, static_cast<uint32_t>(min));
313
30
    }
314
315
    // 3.1 save original value.
316
97.8k
    if (is_keep_original_value) {
317
0
        bit_width = sizeof(T) * 8;
318
0
        uint32_t len = _buffered_values_num * bit_width;
319
0
        _buffer->reserve(_buffer->size() + len);
320
0
        size_t origin_size = _buffer->size();
321
0
        _buffer->resize(origin_size + len);
322
0
        bit_pack(input, _buffered_values_num, bit_width, _buffer->data() + origin_size);
323
97.8k
    } else {
324
        // 3.2 bit pack.
325
        // improve for ascending order input, we could use fewer bit
326
97.8k
        T delta_values[FRAME_VALUE_NUM];
327
97.8k
        if (is_ascending) {
328
898
            delta_values[0] = 0;
329
6.34k
            for (uint8_t i = 1; i < _buffered_values_num; ++i) {
330
5.45k
                delta_values[i] = input[i] - input[i - 1];
331
5.45k
            }
332
96.9k
        } else {
333
96.9k
            bit_width = bits(static_cast<T>(max - min));
334
8.45M
            for (uint8_t i = 0; i < _buffered_values_num; ++i) {
335
8.35M
                delta_values[i] = input[i] - min;
336
8.35M
            }
337
96.9k
        }
338
339
97.8k
        uint32_t packing_len = BitUtil::Ceil(_buffered_values_num * bit_width, 8);
340
341
97.8k
        _buffer->reserve(_buffer->size() + packing_len);
342
97.8k
        size_t origin_size = _buffer->size();
343
97.8k
        _buffer->resize(origin_size + packing_len);
344
97.8k
        bit_pack(delta_values, _buffered_values_num, bit_width, _buffer->data() + origin_size);
345
97.8k
    }
346
97.8k
    uint8_t storage_format = 0;
347
97.8k
    if (is_keep_original_value) {
348
0
        storage_format = 2;
349
97.8k
    } else if (is_ascending) {
350
898
        storage_format = 1;
351
898
    }
352
97.8k
    _storage_formats.push_back(storage_format);
353
97.8k
    _bit_widths.push_back(bit_width);
354
355
97.8k
    _buffered_values_num = 0;
356
97.8k
}
Unexecuted instantiation: _ZN5doris10ForEncoderIaE27bit_packing_one_frame_valueEPKa
Unexecuted instantiation: _ZN5doris10ForEncoderIsE27bit_packing_one_frame_valueEPKs
_ZN5doris10ForEncoderIiE27bit_packing_one_frame_valueEPKi
Line
Count
Source
269
18
void ForEncoder<T>::bit_packing_one_frame_value(const T* input) {
270
18
    T min = input[0];
271
18
    T max = input[0];
272
18
    bool is_ascending = true;
273
18
    uint8_t bit_width = 0;
274
18
    T half_max_delta = numeric_limits_max() >> 1;
275
18
    bool is_keep_original_value = false;
276
277
    // 1. make sure order_flag, save_original_value, and find max&min.
278
1.54k
    for (uint8_t i = 1; i < _buffered_values_num; ++i) {
279
1.52k
        if (is_ascending) {
280
1.52k
            if (input[i] < input[i - 1]) {
281
0
                is_ascending = false;
282
1.52k
            } else {
283
1.52k
                if ((input[i] >> 1) - (input[i - 1] >> 1) > half_max_delta) { // overflow
284
0
                    is_keep_original_value = true;
285
1.52k
                } else {
286
1.52k
                    bit_width = std::max(bit_width, bits(input[i] - input[i - 1]));
287
1.52k
                }
288
1.52k
            }
289
1.52k
        }
290
291
1.52k
        if (input[i] < min) {
292
0
            min = input[i];
293
0
            continue;
294
0
        }
295
296
1.52k
        if (input[i] > max) {
297
1.52k
            max = input[i];
298
1.52k
        }
299
1.52k
    }
300
18
    if (!is_ascending) {
301
0
        if ((max >> 1) - (min >> 1) > half_max_delta) {
302
0
            is_keep_original_value = true;
303
0
        }
304
0
    }
305
306
    // 2. save min value.
307
18
    if (sizeof(T) == 16) {
308
0
        put_fixed128_le(_buffer, static_cast<uint128_t>(min));
309
18
    } else if (sizeof(T) == 8) {
310
0
        put_fixed64_le(_buffer, static_cast<uint64_t>(min));
311
18
    } else {
312
18
        put_fixed32_le(_buffer, static_cast<uint32_t>(min));
313
18
    }
314
315
    // 3.1 save original value.
316
18
    if (is_keep_original_value) {
317
0
        bit_width = sizeof(T) * 8;
318
0
        uint32_t len = _buffered_values_num * bit_width;
319
0
        _buffer->reserve(_buffer->size() + len);
320
0
        size_t origin_size = _buffer->size();
321
0
        _buffer->resize(origin_size + len);
322
0
        bit_pack(input, _buffered_values_num, bit_width, _buffer->data() + origin_size);
323
18
    } else {
324
        // 3.2 bit pack.
325
        // improve for ascending order input, we could use fewer bit
326
18
        T delta_values[FRAME_VALUE_NUM];
327
18
        if (is_ascending) {
328
18
            delta_values[0] = 0;
329
1.54k
            for (uint8_t i = 1; i < _buffered_values_num; ++i) {
330
1.52k
                delta_values[i] = input[i] - input[i - 1];
331
1.52k
            }
332
18
        } else {
333
0
            bit_width = bits(static_cast<T>(max - min));
334
0
            for (uint8_t i = 0; i < _buffered_values_num; ++i) {
335
0
                delta_values[i] = input[i] - min;
336
0
            }
337
0
        }
338
339
18
        uint32_t packing_len = BitUtil::Ceil(_buffered_values_num * bit_width, 8);
340
341
18
        _buffer->reserve(_buffer->size() + packing_len);
342
18
        size_t origin_size = _buffer->size();
343
18
        _buffer->resize(origin_size + packing_len);
344
18
        bit_pack(delta_values, _buffered_values_num, bit_width, _buffer->data() + origin_size);
345
18
    }
346
18
    uint8_t storage_format = 0;
347
18
    if (is_keep_original_value) {
348
0
        storage_format = 2;
349
18
    } else if (is_ascending) {
350
18
        storage_format = 1;
351
18
    }
352
18
    _storage_formats.push_back(storage_format);
353
18
    _bit_widths.push_back(bit_width);
354
355
18
    _buffered_values_num = 0;
356
18
}
_ZN5doris10ForEncoderIlE27bit_packing_one_frame_valueEPKl
Line
Count
Source
269
48.9k
void ForEncoder<T>::bit_packing_one_frame_value(const T* input) {
270
48.9k
    T min = input[0];
271
48.9k
    T max = input[0];
272
48.9k
    bool is_ascending = true;
273
48.9k
    uint8_t bit_width = 0;
274
48.9k
    T half_max_delta = numeric_limits_max() >> 1;
275
48.9k
    bool is_keep_original_value = false;
276
277
    // 1. make sure order_flag, save_original_value, and find max&min.
278
4.17M
    for (uint8_t i = 1; i < _buffered_values_num; ++i) {
279
4.13M
        if (is_ascending) {
280
86.7k
            if (input[i] < input[i - 1]) {
281
48.4k
                is_ascending = false;
282
48.4k
            } else {
283
38.2k
                if ((input[i] >> 1) - (input[i - 1] >> 1) > half_max_delta) { // overflow
284
0
                    is_keep_original_value = true;
285
38.2k
                } else {
286
38.2k
                    bit_width = std::max(bit_width, bits(input[i] - input[i - 1]));
287
38.2k
                }
288
38.2k
            }
289
86.7k
        }
290
291
4.13M
        if (input[i] < min) {
292
176k
            min = input[i];
293
176k
            continue;
294
176k
        }
295
296
3.95M
        if (input[i] > max) {
297
179k
            max = input[i];
298
179k
        }
299
3.95M
    }
300
48.9k
    if (!is_ascending) {
301
48.4k
        if ((max >> 1) - (min >> 1) > half_max_delta) {
302
0
            is_keep_original_value = true;
303
0
        }
304
48.4k
    }
305
306
    // 2. save min value.
307
48.9k
    if (sizeof(T) == 16) {
308
0
        put_fixed128_le(_buffer, static_cast<uint128_t>(min));
309
48.9k
    } else if (sizeof(T) == 8) {
310
48.9k
        put_fixed64_le(_buffer, static_cast<uint64_t>(min));
311
48.9k
    } else {
312
0
        put_fixed32_le(_buffer, static_cast<uint32_t>(min));
313
0
    }
314
315
    // 3.1 save original value.
316
48.9k
    if (is_keep_original_value) {
317
0
        bit_width = sizeof(T) * 8;
318
0
        uint32_t len = _buffered_values_num * bit_width;
319
0
        _buffer->reserve(_buffer->size() + len);
320
0
        size_t origin_size = _buffer->size();
321
0
        _buffer->resize(origin_size + len);
322
0
        bit_pack(input, _buffered_values_num, bit_width, _buffer->data() + origin_size);
323
48.9k
    } else {
324
        // 3.2 bit pack.
325
        // improve for ascending order input, we could use fewer bit
326
48.9k
        T delta_values[FRAME_VALUE_NUM];
327
48.9k
        if (is_ascending) {
328
440
            delta_values[0] = 0;
329
2.59k
            for (uint8_t i = 1; i < _buffered_values_num; ++i) {
330
2.15k
                delta_values[i] = input[i] - input[i - 1];
331
2.15k
            }
332
48.4k
        } else {
333
48.4k
            bit_width = bits(static_cast<T>(max - min));
334
4.22M
            for (uint8_t i = 0; i < _buffered_values_num; ++i) {
335
4.17M
                delta_values[i] = input[i] - min;
336
4.17M
            }
337
48.4k
        }
338
339
48.9k
        uint32_t packing_len = BitUtil::Ceil(_buffered_values_num * bit_width, 8);
340
341
48.9k
        _buffer->reserve(_buffer->size() + packing_len);
342
48.9k
        size_t origin_size = _buffer->size();
343
48.9k
        _buffer->resize(origin_size + packing_len);
344
48.9k
        bit_pack(delta_values, _buffered_values_num, bit_width, _buffer->data() + origin_size);
345
48.9k
    }
346
48.9k
    uint8_t storage_format = 0;
347
48.9k
    if (is_keep_original_value) {
348
0
        storage_format = 2;
349
48.9k
    } else if (is_ascending) {
350
440
        storage_format = 1;
351
440
    }
352
48.9k
    _storage_formats.push_back(storage_format);
353
48.9k
    _bit_widths.push_back(bit_width);
354
355
48.9k
    _buffered_values_num = 0;
356
48.9k
}
_ZN5doris10ForEncoderInE27bit_packing_one_frame_valueEPKn
Line
Count
Source
269
48.8k
void ForEncoder<T>::bit_packing_one_frame_value(const T* input) {
270
48.8k
    T min = input[0];
271
48.8k
    T max = input[0];
272
48.8k
    bool is_ascending = true;
273
48.8k
    uint8_t bit_width = 0;
274
48.8k
    T half_max_delta = numeric_limits_max() >> 1;
275
48.8k
    bool is_keep_original_value = false;
276
277
    // 1. make sure order_flag, save_original_value, and find max&min.
278
4.17M
    for (uint8_t i = 1; i < _buffered_values_num; ++i) {
279
4.12M
        if (is_ascending) {
280
83.1k
            if (input[i] < input[i - 1]) {
281
48.4k
                is_ascending = false;
282
48.4k
            } else {
283
34.7k
                if ((input[i] >> 1) - (input[i - 1] >> 1) > half_max_delta) { // overflow
284
0
                    is_keep_original_value = true;
285
34.7k
                } else {
286
34.7k
                    bit_width = std::max(bit_width, bits(input[i] - input[i - 1]));
287
34.7k
                }
288
34.7k
            }
289
83.1k
        }
290
291
4.12M
        if (input[i] < min) {
292
185k
            min = input[i];
293
185k
            continue;
294
185k
        }
295
296
3.94M
        if (input[i] > max) {
297
185k
            max = input[i];
298
185k
        }
299
3.94M
    }
300
48.8k
    if (!is_ascending) {
301
48.4k
        if ((max >> 1) - (min >> 1) > half_max_delta) {
302
0
            is_keep_original_value = true;
303
0
        }
304
48.4k
    }
305
306
    // 2. save min value.
307
48.8k
    if (sizeof(T) == 16) {
308
48.8k
        put_fixed128_le(_buffer, static_cast<uint128_t>(min));
309
48.8k
    } else if (sizeof(T) == 8) {
310
0
        put_fixed64_le(_buffer, static_cast<uint64_t>(min));
311
0
    } else {
312
0
        put_fixed32_le(_buffer, static_cast<uint32_t>(min));
313
0
    }
314
315
    // 3.1 save original value.
316
48.8k
    if (is_keep_original_value) {
317
0
        bit_width = sizeof(T) * 8;
318
0
        uint32_t len = _buffered_values_num * bit_width;
319
0
        _buffer->reserve(_buffer->size() + len);
320
0
        size_t origin_size = _buffer->size();
321
0
        _buffer->resize(origin_size + len);
322
0
        bit_pack(input, _buffered_values_num, bit_width, _buffer->data() + origin_size);
323
48.8k
    } else {
324
        // 3.2 bit pack.
325
        // improve for ascending order input, we could use fewer bit
326
48.8k
        T delta_values[FRAME_VALUE_NUM];
327
48.8k
        if (is_ascending) {
328
428
            delta_values[0] = 0;
329
676
            for (uint8_t i = 1; i < _buffered_values_num; ++i) {
330
248
                delta_values[i] = input[i] - input[i - 1];
331
248
            }
332
48.4k
        } else {
333
48.4k
            bit_width = bits(static_cast<T>(max - min));
334
4.22M
            for (uint8_t i = 0; i < _buffered_values_num; ++i) {
335
4.17M
                delta_values[i] = input[i] - min;
336
4.17M
            }
337
48.4k
        }
338
339
48.8k
        uint32_t packing_len = BitUtil::Ceil(_buffered_values_num * bit_width, 8);
340
341
48.8k
        _buffer->reserve(_buffer->size() + packing_len);
342
48.8k
        size_t origin_size = _buffer->size();
343
48.8k
        _buffer->resize(origin_size + packing_len);
344
48.8k
        bit_pack(delta_values, _buffered_values_num, bit_width, _buffer->data() + origin_size);
345
48.8k
    }
346
48.8k
    uint8_t storage_format = 0;
347
48.8k
    if (is_keep_original_value) {
348
0
        storage_format = 2;
349
48.8k
    } else if (is_ascending) {
350
428
        storage_format = 1;
351
428
    }
352
48.8k
    _storage_formats.push_back(storage_format);
353
48.8k
    _bit_widths.push_back(bit_width);
354
355
48.8k
    _buffered_values_num = 0;
356
48.8k
}
Unexecuted instantiation: _ZN5doris10ForEncoderIhE27bit_packing_one_frame_valueEPKh
Unexecuted instantiation: _ZN5doris10ForEncoderItE27bit_packing_one_frame_valueEPKt
_ZN5doris10ForEncoderIjE27bit_packing_one_frame_valueEPKj
Line
Count
Source
269
12
void ForEncoder<T>::bit_packing_one_frame_value(const T* input) {
270
12
    T min = input[0];
271
12
    T max = input[0];
272
12
    bool is_ascending = true;
273
12
    uint8_t bit_width = 0;
274
12
    T half_max_delta = numeric_limits_max() >> 1;
275
12
    bool is_keep_original_value = false;
276
277
    // 1. make sure order_flag, save_original_value, and find max&min.
278
1.53k
    for (uint8_t i = 1; i < _buffered_values_num; ++i) {
279
1.52k
        if (is_ascending) {
280
1.52k
            if (input[i] < input[i - 1]) {
281
0
                is_ascending = false;
282
1.52k
            } else {
283
1.52k
                if ((input[i] >> 1) - (input[i - 1] >> 1) > half_max_delta) { // overflow
284
0
                    is_keep_original_value = true;
285
1.52k
                } else {
286
1.52k
                    bit_width = std::max(bit_width, bits(input[i] - input[i - 1]));
287
1.52k
                }
288
1.52k
            }
289
1.52k
        }
290
291
1.52k
        if (input[i] < min) {
292
0
            min = input[i];
293
0
            continue;
294
0
        }
295
296
1.52k
        if (input[i] > max) {
297
1.52k
            max = input[i];
298
1.52k
        }
299
1.52k
    }
300
12
    if (!is_ascending) {
301
0
        if ((max >> 1) - (min >> 1) > half_max_delta) {
302
0
            is_keep_original_value = true;
303
0
        }
304
0
    }
305
306
    // 2. save min value.
307
12
    if (sizeof(T) == 16) {
308
0
        put_fixed128_le(_buffer, static_cast<uint128_t>(min));
309
12
    } else if (sizeof(T) == 8) {
310
0
        put_fixed64_le(_buffer, static_cast<uint64_t>(min));
311
12
    } else {
312
12
        put_fixed32_le(_buffer, static_cast<uint32_t>(min));
313
12
    }
314
315
    // 3.1 save original value.
316
12
    if (is_keep_original_value) {
317
0
        bit_width = sizeof(T) * 8;
318
0
        uint32_t len = _buffered_values_num * bit_width;
319
0
        _buffer->reserve(_buffer->size() + len);
320
0
        size_t origin_size = _buffer->size();
321
0
        _buffer->resize(origin_size + len);
322
0
        bit_pack(input, _buffered_values_num, bit_width, _buffer->data() + origin_size);
323
12
    } else {
324
        // 3.2 bit pack.
325
        // improve for ascending order input, we could use fewer bit
326
12
        T delta_values[FRAME_VALUE_NUM];
327
12
        if (is_ascending) {
328
12
            delta_values[0] = 0;
329
1.53k
            for (uint8_t i = 1; i < _buffered_values_num; ++i) {
330
1.52k
                delta_values[i] = input[i] - input[i - 1];
331
1.52k
            }
332
12
        } else {
333
0
            bit_width = bits(static_cast<T>(max - min));
334
0
            for (uint8_t i = 0; i < _buffered_values_num; ++i) {
335
0
                delta_values[i] = input[i] - min;
336
0
            }
337
0
        }
338
339
12
        uint32_t packing_len = BitUtil::Ceil(_buffered_values_num * bit_width, 8);
340
341
12
        _buffer->reserve(_buffer->size() + packing_len);
342
12
        size_t origin_size = _buffer->size();
343
12
        _buffer->resize(origin_size + packing_len);
344
12
        bit_pack(delta_values, _buffered_values_num, bit_width, _buffer->data() + origin_size);
345
12
    }
346
12
    uint8_t storage_format = 0;
347
12
    if (is_keep_original_value) {
348
0
        storage_format = 2;
349
12
    } else if (is_ascending) {
350
12
        storage_format = 1;
351
12
    }
352
12
    _storage_formats.push_back(storage_format);
353
12
    _bit_widths.push_back(bit_width);
354
355
12
    _buffered_values_num = 0;
356
12
}
Unexecuted instantiation: _ZN5doris10ForEncoderImE27bit_packing_one_frame_valueEPKm
Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE27bit_packing_one_frame_valueEPKS1_
Unexecuted instantiation: _ZN5doris10ForEncoderIoE27bit_packing_one_frame_valueEPKo
357
358
template <typename T>
359
65.3k
uint32_t ForEncoder<T>::flush() {
360
65.3k
    if (_buffered_values_num != 0) {
361
65.0k
        bit_packing_one_frame_value(_buffered_values);
362
65.0k
    }
363
364
    // write the footer:
365
    // 1 _storage_formats and bit_widths
366
65.3k
    DCHECK(_storage_formats.size() == _bit_widths.size())
367
0
            << "Size of _storage_formats and _bit_widths should be equal.";
368
163k
    for (size_t i = 0; i < _storage_formats.size(); i++) {
369
97.8k
        _buffer->append(&_storage_formats[i], 1);
370
97.8k
        _buffer->append(&_bit_widths[i], 1);
371
97.8k
    }
372
    // 2 frame_value_num and values_num
373
65.3k
    uint8_t frame_value_num = FRAME_VALUE_NUM;
374
65.3k
    _buffer->append(&frame_value_num, 1);
375
65.3k
    put_fixed32_le(_buffer, _values_num);
376
377
65.3k
    return cast_set<uint32_t>(_buffer->size());
378
65.3k
}
Unexecuted instantiation: _ZN5doris10ForEncoderIaE5flushEv
Unexecuted instantiation: _ZN5doris10ForEncoderIsE5flushEv
_ZN5doris10ForEncoderIiE5flushEv
Line
Count
Source
359
14
uint32_t ForEncoder<T>::flush() {
360
14
    if (_buffered_values_num != 0) {
361
8
        bit_packing_one_frame_value(_buffered_values);
362
8
    }
363
364
    // write the footer:
365
    // 1 _storage_formats and bit_widths
366
14
    DCHECK(_storage_formats.size() == _bit_widths.size())
367
0
            << "Size of _storage_formats and _bit_widths should be equal.";
368
32
    for (size_t i = 0; i < _storage_formats.size(); i++) {
369
18
        _buffer->append(&_storage_formats[i], 1);
370
18
        _buffer->append(&_bit_widths[i], 1);
371
18
    }
372
    // 2 frame_value_num and values_num
373
14
    uint8_t frame_value_num = FRAME_VALUE_NUM;
374
14
    _buffer->append(&frame_value_num, 1);
375
14
    put_fixed32_le(_buffer, _values_num);
376
377
14
    return cast_set<uint32_t>(_buffer->size());
378
14
}
_ZN5doris10ForEncoderIlE5flushEv
Line
Count
Source
359
32.6k
uint32_t ForEncoder<T>::flush() {
360
32.6k
    if (_buffered_values_num != 0) {
361
32.5k
        bit_packing_one_frame_value(_buffered_values);
362
32.5k
    }
363
364
    // write the footer:
365
    // 1 _storage_formats and bit_widths
366
32.6k
    DCHECK(_storage_formats.size() == _bit_widths.size())
367
0
            << "Size of _storage_formats and _bit_widths should be equal.";
368
81.5k
    for (size_t i = 0; i < _storage_formats.size(); i++) {
369
48.9k
        _buffer->append(&_storage_formats[i], 1);
370
48.9k
        _buffer->append(&_bit_widths[i], 1);
371
48.9k
    }
372
    // 2 frame_value_num and values_num
373
32.6k
    uint8_t frame_value_num = FRAME_VALUE_NUM;
374
32.6k
    _buffer->append(&frame_value_num, 1);
375
32.6k
    put_fixed32_le(_buffer, _values_num);
376
377
32.6k
    return cast_set<uint32_t>(_buffer->size());
378
32.6k
}
_ZN5doris10ForEncoderInE5flushEv
Line
Count
Source
359
32.6k
uint32_t ForEncoder<T>::flush() {
360
32.6k
    if (_buffered_values_num != 0) {
361
32.5k
        bit_packing_one_frame_value(_buffered_values);
362
32.5k
    }
363
364
    // write the footer:
365
    // 1 _storage_formats and bit_widths
366
32.6k
    DCHECK(_storage_formats.size() == _bit_widths.size())
367
0
            << "Size of _storage_formats and _bit_widths should be equal.";
368
81.5k
    for (size_t i = 0; i < _storage_formats.size(); i++) {
369
48.8k
        _buffer->append(&_storage_formats[i], 1);
370
48.8k
        _buffer->append(&_bit_widths[i], 1);
371
48.8k
    }
372
    // 2 frame_value_num and values_num
373
32.6k
    uint8_t frame_value_num = FRAME_VALUE_NUM;
374
32.6k
    _buffer->append(&frame_value_num, 1);
375
32.6k
    put_fixed32_le(_buffer, _values_num);
376
377
32.6k
    return cast_set<uint32_t>(_buffer->size());
378
32.6k
}
Unexecuted instantiation: _ZN5doris10ForEncoderIhE5flushEv
Unexecuted instantiation: _ZN5doris10ForEncoderItE5flushEv
_ZN5doris10ForEncoderIjE5flushEv
Line
Count
Source
359
6
uint32_t ForEncoder<T>::flush() {
360
6
    if (_buffered_values_num != 0) {
361
0
        bit_packing_one_frame_value(_buffered_values);
362
0
    }
363
364
    // write the footer:
365
    // 1 _storage_formats and bit_widths
366
6
    DCHECK(_storage_formats.size() == _bit_widths.size())
367
0
            << "Size of _storage_formats and _bit_widths should be equal.";
368
18
    for (size_t i = 0; i < _storage_formats.size(); i++) {
369
12
        _buffer->append(&_storage_formats[i], 1);
370
12
        _buffer->append(&_bit_widths[i], 1);
371
12
    }
372
    // 2 frame_value_num and values_num
373
6
    uint8_t frame_value_num = FRAME_VALUE_NUM;
374
6
    _buffer->append(&frame_value_num, 1);
375
6
    put_fixed32_le(_buffer, _values_num);
376
377
6
    return cast_set<uint32_t>(_buffer->size());
378
6
}
Unexecuted instantiation: _ZN5doris10ForEncoderImE5flushEv
Unexecuted instantiation: _ZN5doris10ForEncoderINS_8uint24_tEE5flushEv
Unexecuted instantiation: _ZN5doris10ForEncoderIoE5flushEv
379
380
template <typename T>
381
97.8k
const T ForEncoder<T>::numeric_limits_max() {
382
97.8k
    return std::numeric_limits<T>::max();
383
97.8k
}
Unexecuted instantiation: _ZN5doris10ForEncoderIaE18numeric_limits_maxEv
Unexecuted instantiation: _ZN5doris10ForEncoderIsE18numeric_limits_maxEv
_ZN5doris10ForEncoderIiE18numeric_limits_maxEv
Line
Count
Source
381
18
const T ForEncoder<T>::numeric_limits_max() {
382
18
    return std::numeric_limits<T>::max();
383
18
}
_ZN5doris10ForEncoderIlE18numeric_limits_maxEv
Line
Count
Source
381
48.9k
const T ForEncoder<T>::numeric_limits_max() {
382
48.9k
    return std::numeric_limits<T>::max();
383
48.9k
}
_ZN5doris10ForEncoderInE18numeric_limits_maxEv
Line
Count
Source
381
48.8k
const T ForEncoder<T>::numeric_limits_max() {
382
48.8k
    return std::numeric_limits<T>::max();
383
48.8k
}
Unexecuted instantiation: _ZN5doris10ForEncoderIhE18numeric_limits_maxEv
Unexecuted instantiation: _ZN5doris10ForEncoderItE18numeric_limits_maxEv
_ZN5doris10ForEncoderIjE18numeric_limits_maxEv
Line
Count
Source
381
12
const T ForEncoder<T>::numeric_limits_max() {
382
12
    return std::numeric_limits<T>::max();
383
12
}
Unexecuted instantiation: _ZN5doris10ForEncoderImE18numeric_limits_maxEv
Unexecuted instantiation: _ZN5doris10ForEncoderIoE18numeric_limits_maxEv
384
385
template <>
386
0
const uint24_t ForEncoder<uint24_t>::numeric_limits_max() {
387
0
    return 0XFFFFFF;
388
0
}
389
390
template <typename T>
391
65.3k
bool ForDecoder<T>::init() {
392
    // When row count is zero, the minimum footer size is 5:
393
    // only has ValuesNum(4) + FrameValueNum(1)
394
65.3k
    if (_buffer_len < 5) {
395
0
        return false;
396
0
    }
397
398
65.3k
    _max_frame_size = decode_fixed8(_buffer + _buffer_len - 5);
399
65.3k
    _values_num = decode_fixed32_le(_buffer + _buffer_len - 4);
400
65.3k
    _frame_count = _values_num / _max_frame_size + (_values_num % _max_frame_size != 0);
401
65.3k
    _last_frame_size =
402
65.3k
            cast_set<uint8_t>(_max_frame_size - (_max_frame_size * _frame_count - _values_num));
403
404
65.3k
    size_t bit_width_offset = _buffer_len - 5 - _frame_count * 2;
405
406
    // read _storage_formats, bit_widths and compute frame_offsets
407
65.3k
    u_int32_t frame_start_offset = 0;
408
163k
    for (uint32_t i = 0; i < _frame_count; i++) {
409
97.8k
        uint8_t order_flag = decode_fixed8(_buffer + bit_width_offset);
410
97.8k
        uint8_t bit_width = decode_fixed8(_buffer + bit_width_offset + 1);
411
97.8k
        _bit_widths.push_back(bit_width);
412
97.8k
        _storage_formats.push_back(order_flag);
413
414
97.8k
        bit_width_offset += 2;
415
416
97.8k
        _frame_offsets.push_back(frame_start_offset);
417
97.8k
        if (sizeof(T) == 16) {
418
48.8k
            frame_start_offset += bit_width * _max_frame_size / 8 + 16;
419
48.9k
        } else if (sizeof(T) == 8) {
420
48.9k
            frame_start_offset += bit_width * _max_frame_size / 8 + 8;
421
48.9k
        } else {
422
30
            frame_start_offset += bit_width * _max_frame_size / 8 + 4;
423
30
        }
424
97.8k
    }
425
426
65.3k
    _out_buffer.resize(_max_frame_size);
427
65.3k
    _parsed = true;
428
429
65.3k
    return true;
430
65.3k
}
Unexecuted instantiation: _ZN5doris10ForDecoderIaE4initEv
Unexecuted instantiation: _ZN5doris10ForDecoderIsE4initEv
_ZN5doris10ForDecoderIiE4initEv
Line
Count
Source
391
14
bool ForDecoder<T>::init() {
392
    // When row count is zero, the minimum footer size is 5:
393
    // only has ValuesNum(4) + FrameValueNum(1)
394
14
    if (_buffer_len < 5) {
395
0
        return false;
396
0
    }
397
398
14
    _max_frame_size = decode_fixed8(_buffer + _buffer_len - 5);
399
14
    _values_num = decode_fixed32_le(_buffer + _buffer_len - 4);
400
14
    _frame_count = _values_num / _max_frame_size + (_values_num % _max_frame_size != 0);
401
14
    _last_frame_size =
402
14
            cast_set<uint8_t>(_max_frame_size - (_max_frame_size * _frame_count - _values_num));
403
404
14
    size_t bit_width_offset = _buffer_len - 5 - _frame_count * 2;
405
406
    // read _storage_formats, bit_widths and compute frame_offsets
407
14
    u_int32_t frame_start_offset = 0;
408
32
    for (uint32_t i = 0; i < _frame_count; i++) {
409
18
        uint8_t order_flag = decode_fixed8(_buffer + bit_width_offset);
410
18
        uint8_t bit_width = decode_fixed8(_buffer + bit_width_offset + 1);
411
18
        _bit_widths.push_back(bit_width);
412
18
        _storage_formats.push_back(order_flag);
413
414
18
        bit_width_offset += 2;
415
416
18
        _frame_offsets.push_back(frame_start_offset);
417
18
        if (sizeof(T) == 16) {
418
0
            frame_start_offset += bit_width * _max_frame_size / 8 + 16;
419
18
        } else if (sizeof(T) == 8) {
420
0
            frame_start_offset += bit_width * _max_frame_size / 8 + 8;
421
18
        } else {
422
18
            frame_start_offset += bit_width * _max_frame_size / 8 + 4;
423
18
        }
424
18
    }
425
426
14
    _out_buffer.resize(_max_frame_size);
427
14
    _parsed = true;
428
429
14
    return true;
430
14
}
_ZN5doris10ForDecoderIlE4initEv
Line
Count
Source
391
32.6k
bool ForDecoder<T>::init() {
392
    // When row count is zero, the minimum footer size is 5:
393
    // only has ValuesNum(4) + FrameValueNum(1)
394
32.6k
    if (_buffer_len < 5) {
395
0
        return false;
396
0
    }
397
398
32.6k
    _max_frame_size = decode_fixed8(_buffer + _buffer_len - 5);
399
32.6k
    _values_num = decode_fixed32_le(_buffer + _buffer_len - 4);
400
32.6k
    _frame_count = _values_num / _max_frame_size + (_values_num % _max_frame_size != 0);
401
32.6k
    _last_frame_size =
402
32.6k
            cast_set<uint8_t>(_max_frame_size - (_max_frame_size * _frame_count - _values_num));
403
404
32.6k
    size_t bit_width_offset = _buffer_len - 5 - _frame_count * 2;
405
406
    // read _storage_formats, bit_widths and compute frame_offsets
407
32.6k
    u_int32_t frame_start_offset = 0;
408
81.5k
    for (uint32_t i = 0; i < _frame_count; i++) {
409
48.9k
        uint8_t order_flag = decode_fixed8(_buffer + bit_width_offset);
410
48.9k
        uint8_t bit_width = decode_fixed8(_buffer + bit_width_offset + 1);
411
48.9k
        _bit_widths.push_back(bit_width);
412
48.9k
        _storage_formats.push_back(order_flag);
413
414
48.9k
        bit_width_offset += 2;
415
416
48.9k
        _frame_offsets.push_back(frame_start_offset);
417
48.9k
        if (sizeof(T) == 16) {
418
0
            frame_start_offset += bit_width * _max_frame_size / 8 + 16;
419
48.9k
        } else if (sizeof(T) == 8) {
420
48.9k
            frame_start_offset += bit_width * _max_frame_size / 8 + 8;
421
48.9k
        } else {
422
0
            frame_start_offset += bit_width * _max_frame_size / 8 + 4;
423
0
        }
424
48.9k
    }
425
426
32.6k
    _out_buffer.resize(_max_frame_size);
427
32.6k
    _parsed = true;
428
429
32.6k
    return true;
430
32.6k
}
_ZN5doris10ForDecoderInE4initEv
Line
Count
Source
391
32.6k
bool ForDecoder<T>::init() {
392
    // When row count is zero, the minimum footer size is 5:
393
    // only has ValuesNum(4) + FrameValueNum(1)
394
32.6k
    if (_buffer_len < 5) {
395
0
        return false;
396
0
    }
397
398
32.6k
    _max_frame_size = decode_fixed8(_buffer + _buffer_len - 5);
399
32.6k
    _values_num = decode_fixed32_le(_buffer + _buffer_len - 4);
400
32.6k
    _frame_count = _values_num / _max_frame_size + (_values_num % _max_frame_size != 0);
401
32.6k
    _last_frame_size =
402
32.6k
            cast_set<uint8_t>(_max_frame_size - (_max_frame_size * _frame_count - _values_num));
403
404
32.6k
    size_t bit_width_offset = _buffer_len - 5 - _frame_count * 2;
405
406
    // read _storage_formats, bit_widths and compute frame_offsets
407
32.6k
    u_int32_t frame_start_offset = 0;
408
81.5k
    for (uint32_t i = 0; i < _frame_count; i++) {
409
48.8k
        uint8_t order_flag = decode_fixed8(_buffer + bit_width_offset);
410
48.8k
        uint8_t bit_width = decode_fixed8(_buffer + bit_width_offset + 1);
411
48.8k
        _bit_widths.push_back(bit_width);
412
48.8k
        _storage_formats.push_back(order_flag);
413
414
48.8k
        bit_width_offset += 2;
415
416
48.8k
        _frame_offsets.push_back(frame_start_offset);
417
48.8k
        if (sizeof(T) == 16) {
418
48.8k
            frame_start_offset += bit_width * _max_frame_size / 8 + 16;
419
48.8k
        } else if (sizeof(T) == 8) {
420
0
            frame_start_offset += bit_width * _max_frame_size / 8 + 8;
421
0
        } else {
422
0
            frame_start_offset += bit_width * _max_frame_size / 8 + 4;
423
0
        }
424
48.8k
    }
425
426
32.6k
    _out_buffer.resize(_max_frame_size);
427
32.6k
    _parsed = true;
428
429
32.6k
    return true;
430
32.6k
}
Unexecuted instantiation: _ZN5doris10ForDecoderIhE4initEv
Unexecuted instantiation: _ZN5doris10ForDecoderItE4initEv
_ZN5doris10ForDecoderIjE4initEv
Line
Count
Source
391
6
bool ForDecoder<T>::init() {
392
    // When row count is zero, the minimum footer size is 5:
393
    // only has ValuesNum(4) + FrameValueNum(1)
394
6
    if (_buffer_len < 5) {
395
0
        return false;
396
0
    }
397
398
6
    _max_frame_size = decode_fixed8(_buffer + _buffer_len - 5);
399
6
    _values_num = decode_fixed32_le(_buffer + _buffer_len - 4);
400
6
    _frame_count = _values_num / _max_frame_size + (_values_num % _max_frame_size != 0);
401
6
    _last_frame_size =
402
6
            cast_set<uint8_t>(_max_frame_size - (_max_frame_size * _frame_count - _values_num));
403
404
6
    size_t bit_width_offset = _buffer_len - 5 - _frame_count * 2;
405
406
    // read _storage_formats, bit_widths and compute frame_offsets
407
6
    u_int32_t frame_start_offset = 0;
408
18
    for (uint32_t i = 0; i < _frame_count; i++) {
409
12
        uint8_t order_flag = decode_fixed8(_buffer + bit_width_offset);
410
12
        uint8_t bit_width = decode_fixed8(_buffer + bit_width_offset + 1);
411
12
        _bit_widths.push_back(bit_width);
412
12
        _storage_formats.push_back(order_flag);
413
414
12
        bit_width_offset += 2;
415
416
12
        _frame_offsets.push_back(frame_start_offset);
417
12
        if (sizeof(T) == 16) {
418
0
            frame_start_offset += bit_width * _max_frame_size / 8 + 16;
419
12
        } else if (sizeof(T) == 8) {
420
0
            frame_start_offset += bit_width * _max_frame_size / 8 + 8;
421
12
        } else {
422
12
            frame_start_offset += bit_width * _max_frame_size / 8 + 4;
423
12
        }
424
12
    }
425
426
6
    _out_buffer.resize(_max_frame_size);
427
6
    _parsed = true;
428
429
6
    return true;
430
6
}
Unexecuted instantiation: _ZN5doris10ForDecoderImE4initEv
Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE4initEv
Unexecuted instantiation: _ZN5doris10ForDecoderIoE4initEv
431
432
// todo(kks): improve this method by SIMD instructions
433
434
template <typename T>
435
template <typename U>
436
void ForDecoder<T>::bit_unpack_optimize(const uint8_t* input, uint8_t in_num, int bit_width,
437
162k
                                        T* output) {
438
162k
    static_assert(std::is_same<U, int64_t>::value || std::is_same<U, __int128_t>::value,
439
162k
                  "bit_unpack_optimize only supports U = int64_t or __int128_t");
440
162k
    constexpr int u_size = sizeof(U);                   // Size of U
441
162k
    constexpr int u_size_shift = (u_size == 8) ? 3 : 4; // log2(u_size)
442
162k
    int valid_bit = 0;                                  // How many valid bits
443
162k
    int need_bit = 0;                                   // still need
444
162k
    size_t input_size = (in_num * bit_width + 7) >> 3;  // input's size
445
162k
    int full_batch_size =
446
162k
            cast_set<int>((input_size >> u_size_shift)
447
162k
                          << u_size_shift);     // Adjust input_size to a multiple of u_size
448
162k
    int tail_count = input_size & (u_size - 1); // The remainder of input_size modulo u_size.
449
    // The number of bits in input to adjust to multiples of 8 and thus more
450
162k
    int more_bit = cast_set<int>((input_size << 3) - (in_num * bit_width));
451
452
    // to ensure that only bit_width bits are valid
453
162k
    T output_mask;
454
162k
    if (bit_width >= static_cast<int>(sizeof(T) * 8)) {
455
0
        output_mask = static_cast<T>(~T(0));
456
162k
    } else {
457
162k
        output_mask = static_cast<T>((static_cast<T>(1) << bit_width) - 1);
458
162k
    }
459
460
162k
    U s = 0; // Temporary buffer for bitstream: aggregates input bytes into a large integer for unpacking
461
462
8.96M
    for (int i = 0; i < full_batch_size; i += u_size) {
463
8.80M
        s = 0;
464
465
8.80M
        s = to_endian<std::endian::big>(*((U*)(input + i)));
466
467
        // Determine what the valid bits are based on u_size
468
8.80M
        valid_bit = u_size << 3;
469
470
        // If input_size is exactly a multiple of 8, then need to remove the last more_bit in the last loop.
471
8.80M
        if (tail_count == 0 && i == full_batch_size - u_size) {
472
43.5k
            valid_bit -= more_bit;
473
43.5k
            s >>= more_bit;
474
43.5k
        }
475
476
8.80M
        if (need_bit) {
477
            // The last time we take away the high bit_width - need_bit,
478
            // we need to make up the rest of the need_bit from the width.
479
            // Use valid_bit - need_bit to compute high need_bit bits of s
480
            // perform an AND operation to ensure that only need_bit bits are valid
481
8.18M
            auto mask = (static_cast<U>(1) << need_bit) - 1;
482
8.18M
            auto shifted = s >> (valid_bit - need_bit);
483
8.18M
            auto masked_result = shifted & mask;
484
8.18M
            if constexpr (sizeof(T) <= 4) {
485
0
                *output |= static_cast<T>(static_cast<uint32_t>(masked_result));
486
8.18M
            } else {
487
8.18M
                *output |= static_cast<T>(masked_result);
488
8.18M
            }
489
8.18M
            output++;
490
8.18M
            valid_bit -= need_bit;
491
8.18M
        }
492
493
8.80M
        int num = valid_bit / bit_width;             // How many outputs can be processed at a time
494
8.80M
        int remainder = valid_bit - num * bit_width; // How many bits are left to store
495
496
        // Starting with the highest valid bit, take out bit_width bits in sequence
497
        // perform an AND operation with output_mask to ensure that only bit_width bits are valid
498
        // (num-j-1) * bit_width used to calculate how many bits need to be removed at the end
499
        // But since there are still remainder bits that can't be processed, need to add the remainder
500
17.0M
        for (int j = 0; j < num; j++) {
501
8.22M
            *output =
502
8.22M
                    static_cast<T>((s >> (((num - j - 1) * bit_width) + remainder)) & output_mask);
503
8.22M
            output++;
504
8.22M
        }
505
506
8.80M
        if (remainder) {
507
            // Process the last remaining remainder bit.
508
            // y = (s & ((static_cast<U>(1) << remainder) - 1)) extract the last remainder bits.
509
            // output = y << (bit_width - remainder) Use the high bit_width - remainder bit
510
8.28M
            if constexpr (sizeof(T) <= 4) {
511
0
                auto masked_value = static_cast<T>(
512
0
                        static_cast<uint32_t>(s & ((static_cast<U>(1) << remainder) - 1)));
513
0
                *output = static_cast<T>(masked_value << (bit_width - remainder));
514
8.28M
            } else {
515
8.28M
                auto masked_value = static_cast<T>((s & ((static_cast<U>(1) << remainder) - 1)));
516
8.28M
                *output = static_cast<T>(masked_value << (bit_width - remainder));
517
8.28M
            }
518
            // Already have remainder bits, next time need bit_width - remainder bits
519
8.28M
            need_bit = bit_width - remainder;
520
8.28M
        } else {
521
515k
            need_bit = 0;
522
515k
        }
523
8.80M
    }
524
525
    // remainder
526
162k
    if (tail_count) {
527
        // Put the tail_count numbers in the input into s in order, each number occupies 8 bit
528
954k
        for (int i = 0; i < tail_count; i++) {
529
835k
            s <<= 8;
530
835k
            s |= input[full_batch_size + i];
531
835k
        }
532
533
        // tail * 8 is the number of bits that are left to process
534
        // tail * 8 - more_bit is to remove the last more_bit
535
118k
        valid_bit = (tail_count << 3) - more_bit;
536
118k
        s >>= more_bit;
537
538
        // same as before
539
118k
        if (need_bit) {
540
108k
            if constexpr (sizeof(T) <= 4) {
541
0
                *output |= static_cast<T>(static_cast<uint32_t>(
542
0
                        (s >> (valid_bit - need_bit)) & ((static_cast<U>(1) << need_bit) - 1)));
543
108k
            } else {
544
108k
                *output |= static_cast<T>((s >> (valid_bit - need_bit)) &
545
108k
                                          ((static_cast<U>(1) << need_bit) - 1));
546
108k
            }
547
108k
            output++;
548
108k
            valid_bit -= need_bit;
549
108k
        }
550
551
118k
        int num = valid_bit / bit_width; // How many outputs can be processed at a time
552
553
        // same as before
554
253k
        for (int j = 0; j < num; j++) {
555
134k
            *output = static_cast<T>((s >> (((num - j - 1) * bit_width))) & output_mask);
556
134k
            output++;
557
134k
        }
558
118k
    }
559
162k
}
Unexecuted instantiation: _ZN5doris10ForDecoderIaE19bit_unpack_optimizeIlEEvPKhhiPa
Unexecuted instantiation: _ZN5doris10ForDecoderIaE19bit_unpack_optimizeInEEvPKhhiPa
Unexecuted instantiation: _ZN5doris10ForDecoderIsE19bit_unpack_optimizeIlEEvPKhhiPs
Unexecuted instantiation: _ZN5doris10ForDecoderIsE19bit_unpack_optimizeInEEvPKhhiPs
_ZN5doris10ForDecoderIiE19bit_unpack_optimizeIlEEvPKhhiPi
Line
Count
Source
437
18
                                        T* output) {
438
18
    static_assert(std::is_same<U, int64_t>::value || std::is_same<U, __int128_t>::value,
439
18
                  "bit_unpack_optimize only supports U = int64_t or __int128_t");
440
18
    constexpr int u_size = sizeof(U);                   // Size of U
441
18
    constexpr int u_size_shift = (u_size == 8) ? 3 : 4; // log2(u_size)
442
18
    int valid_bit = 0;                                  // How many valid bits
443
18
    int need_bit = 0;                                   // still need
444
18
    size_t input_size = (in_num * bit_width + 7) >> 3;  // input's size
445
18
    int full_batch_size =
446
18
            cast_set<int>((input_size >> u_size_shift)
447
18
                          << u_size_shift);     // Adjust input_size to a multiple of u_size
448
18
    int tail_count = input_size & (u_size - 1); // The remainder of input_size modulo u_size.
449
    // The number of bits in input to adjust to multiples of 8 and thus more
450
18
    int more_bit = cast_set<int>((input_size << 3) - (in_num * bit_width));
451
452
    // to ensure that only bit_width bits are valid
453
18
    T output_mask;
454
18
    if (bit_width >= static_cast<int>(sizeof(T) * 8)) {
455
0
        output_mask = static_cast<T>(~T(0));
456
18
    } else {
457
18
        output_mask = static_cast<T>((static_cast<T>(1) << bit_width) - 1);
458
18
    }
459
460
18
    U s = 0; // Temporary buffer for bitstream: aggregates input bytes into a large integer for unpacking
461
462
42
    for (int i = 0; i < full_batch_size; i += u_size) {
463
24
        s = 0;
464
465
24
        s = to_endian<std::endian::big>(*((U*)(input + i)));
466
467
        // Determine what the valid bits are based on u_size
468
24
        valid_bit = u_size << 3;
469
470
        // If input_size is exactly a multiple of 8, then need to remove the last more_bit in the last loop.
471
24
        if (tail_count == 0 && i == full_batch_size - u_size) {
472
14
            valid_bit -= more_bit;
473
14
            s >>= more_bit;
474
14
        }
475
476
24
        if (need_bit) {
477
            // The last time we take away the high bit_width - need_bit,
478
            // we need to make up the rest of the need_bit from the width.
479
            // Use valid_bit - need_bit to compute high need_bit bits of s
480
            // perform an AND operation to ensure that only need_bit bits are valid
481
0
            auto mask = (static_cast<U>(1) << need_bit) - 1;
482
0
            auto shifted = s >> (valid_bit - need_bit);
483
0
            auto masked_result = shifted & mask;
484
0
            if constexpr (sizeof(T) <= 4) {
485
0
                *output |= static_cast<T>(static_cast<uint32_t>(masked_result));
486
            } else {
487
                *output |= static_cast<T>(masked_result);
488
            }
489
0
            output++;
490
0
            valid_bit -= need_bit;
491
0
        }
492
493
24
        int num = valid_bit / bit_width;             // How many outputs can be processed at a time
494
24
        int remainder = valid_bit - num * bit_width; // How many bits are left to store
495
496
        // Starting with the highest valid bit, take out bit_width bits in sequence
497
        // perform an AND operation with output_mask to ensure that only bit_width bits are valid
498
        // (num-j-1) * bit_width used to calculate how many bits need to be removed at the end
499
        // But since there are still remainder bits that can't be processed, need to add the remainder
500
1.56k
        for (int j = 0; j < num; j++) {
501
1.53k
            *output =
502
1.53k
                    static_cast<T>((s >> (((num - j - 1) * bit_width) + remainder)) & output_mask);
503
1.53k
            output++;
504
1.53k
        }
505
506
24
        if (remainder) {
507
            // Process the last remaining remainder bit.
508
            // y = (s & ((static_cast<U>(1) << remainder) - 1)) extract the last remainder bits.
509
            // output = y << (bit_width - remainder) Use the high bit_width - remainder bit
510
0
            if constexpr (sizeof(T) <= 4) {
511
0
                auto masked_value = static_cast<T>(
512
0
                        static_cast<uint32_t>(s & ((static_cast<U>(1) << remainder) - 1)));
513
0
                *output = static_cast<T>(masked_value << (bit_width - remainder));
514
            } else {
515
                auto masked_value = static_cast<T>((s & ((static_cast<U>(1) << remainder) - 1)));
516
                *output = static_cast<T>(masked_value << (bit_width - remainder));
517
            }
518
            // Already have remainder bits, next time need bit_width - remainder bits
519
0
            need_bit = bit_width - remainder;
520
24
        } else {
521
24
            need_bit = 0;
522
24
        }
523
24
    }
524
525
    // remainder
526
18
    if (tail_count) {
527
        // Put the tail_count numbers in the input into s in order, each number occupies 8 bit
528
4
        for (int i = 0; i < tail_count; i++) {
529
2
            s <<= 8;
530
2
            s |= input[full_batch_size + i];
531
2
        }
532
533
        // tail * 8 is the number of bits that are left to process
534
        // tail * 8 - more_bit is to remove the last more_bit
535
2
        valid_bit = (tail_count << 3) - more_bit;
536
2
        s >>= more_bit;
537
538
        // same as before
539
2
        if (need_bit) {
540
0
            if constexpr (sizeof(T) <= 4) {
541
0
                *output |= static_cast<T>(static_cast<uint32_t>(
542
0
                        (s >> (valid_bit - need_bit)) & ((static_cast<U>(1) << need_bit) - 1)));
543
            } else {
544
                *output |= static_cast<T>((s >> (valid_bit - need_bit)) &
545
                                          ((static_cast<U>(1) << need_bit) - 1));
546
            }
547
0
            output++;
548
0
            valid_bit -= need_bit;
549
0
        }
550
551
2
        int num = valid_bit / bit_width; // How many outputs can be processed at a time
552
553
        // same as before
554
6
        for (int j = 0; j < num; j++) {
555
4
            *output = static_cast<T>((s >> (((num - j - 1) * bit_width))) & output_mask);
556
4
            output++;
557
4
        }
558
2
    }
559
18
}
Unexecuted instantiation: _ZN5doris10ForDecoderIiE19bit_unpack_optimizeInEEvPKhhiPi
_ZN5doris10ForDecoderIlE19bit_unpack_optimizeIlEEvPKhhiPl
Line
Count
Source
437
24.6k
                                        T* output) {
438
24.6k
    static_assert(std::is_same<U, int64_t>::value || std::is_same<U, __int128_t>::value,
439
24.6k
                  "bit_unpack_optimize only supports U = int64_t or __int128_t");
440
24.6k
    constexpr int u_size = sizeof(U);                   // Size of U
441
24.6k
    constexpr int u_size_shift = (u_size == 8) ? 3 : 4; // log2(u_size)
442
24.6k
    int valid_bit = 0;                                  // How many valid bits
443
24.6k
    int need_bit = 0;                                   // still need
444
24.6k
    size_t input_size = (in_num * bit_width + 7) >> 3;  // input's size
445
24.6k
    int full_batch_size =
446
24.6k
            cast_set<int>((input_size >> u_size_shift)
447
24.6k
                          << u_size_shift);     // Adjust input_size to a multiple of u_size
448
24.6k
    int tail_count = input_size & (u_size - 1); // The remainder of input_size modulo u_size.
449
    // The number of bits in input to adjust to multiples of 8 and thus more
450
24.6k
    int more_bit = cast_set<int>((input_size << 3) - (in_num * bit_width));
451
452
    // to ensure that only bit_width bits are valid
453
24.6k
    T output_mask;
454
24.6k
    if (bit_width >= static_cast<int>(sizeof(T) * 8)) {
455
0
        output_mask = static_cast<T>(~T(0));
456
24.6k
    } else {
457
24.6k
        output_mask = static_cast<T>((static_cast<T>(1) << bit_width) - 1);
458
24.6k
    }
459
460
24.6k
    U s = 0; // Temporary buffer for bitstream: aggregates input bytes into a large integer for unpacking
461
462
556k
    for (int i = 0; i < full_batch_size; i += u_size) {
463
532k
        s = 0;
464
465
532k
        s = to_endian<std::endian::big>(*((U*)(input + i)));
466
467
        // Determine what the valid bits are based on u_size
468
532k
        valid_bit = u_size << 3;
469
470
        // If input_size is exactly a multiple of 8, then need to remove the last more_bit in the last loop.
471
532k
        if (tail_count == 0 && i == full_batch_size - u_size) {
472
10.3k
            valid_bit -= more_bit;
473
10.3k
            s >>= more_bit;
474
10.3k
        }
475
476
532k
        if (need_bit) {
477
            // The last time we take away the high bit_width - need_bit,
478
            // we need to make up the rest of the need_bit from the width.
479
            // Use valid_bit - need_bit to compute high need_bit bits of s
480
            // perform an AND operation to ensure that only need_bit bits are valid
481
414k
            auto mask = (static_cast<U>(1) << need_bit) - 1;
482
414k
            auto shifted = s >> (valid_bit - need_bit);
483
414k
            auto masked_result = shifted & mask;
484
            if constexpr (sizeof(T) <= 4) {
485
                *output |= static_cast<T>(static_cast<uint32_t>(masked_result));
486
414k
            } else {
487
414k
                *output |= static_cast<T>(masked_result);
488
414k
            }
489
414k
            output++;
490
414k
            valid_bit -= need_bit;
491
414k
        }
492
493
532k
        int num = valid_bit / bit_width;             // How many outputs can be processed at a time
494
532k
        int remainder = valid_bit - num * bit_width; // How many bits are left to store
495
496
        // Starting with the highest valid bit, take out bit_width bits in sequence
497
        // perform an AND operation with output_mask to ensure that only bit_width bits are valid
498
        // (num-j-1) * bit_width used to calculate how many bits need to be removed at the end
499
        // But since there are still remainder bits that can't be processed, need to add the remainder
500
2.15M
        for (int j = 0; j < num; j++) {
501
1.61M
            *output =
502
1.61M
                    static_cast<T>((s >> (((num - j - 1) * bit_width) + remainder)) & output_mask);
503
1.61M
            output++;
504
1.61M
        }
505
506
532k
        if (remainder) {
507
            // Process the last remaining remainder bit.
508
            // y = (s & ((static_cast<U>(1) << remainder) - 1)) extract the last remainder bits.
509
            // output = y << (bit_width - remainder) Use the high bit_width - remainder bit
510
            if constexpr (sizeof(T) <= 4) {
511
                auto masked_value = static_cast<T>(
512
                        static_cast<uint32_t>(s & ((static_cast<U>(1) << remainder) - 1)));
513
                *output = static_cast<T>(masked_value << (bit_width - remainder));
514
424k
            } else {
515
424k
                auto masked_value = static_cast<T>((s & ((static_cast<U>(1) << remainder) - 1)));
516
424k
                *output = static_cast<T>(masked_value << (bit_width - remainder));
517
424k
            }
518
            // Already have remainder bits, next time need bit_width - remainder bits
519
424k
            need_bit = bit_width - remainder;
520
424k
        } else {
521
107k
            need_bit = 0;
522
107k
        }
523
532k
    }
524
525
    // remainder
526
24.6k
    if (tail_count) {
527
        // Put the tail_count numbers in the input into s in order, each number occupies 8 bit
528
70.0k
        for (int i = 0; i < tail_count; i++) {
529
56.0k
            s <<= 8;
530
56.0k
            s |= input[full_batch_size + i];
531
56.0k
        }
532
533
        // tail * 8 is the number of bits that are left to process
534
        // tail * 8 - more_bit is to remove the last more_bit
535
13.9k
        valid_bit = (tail_count << 3) - more_bit;
536
13.9k
        s >>= more_bit;
537
538
        // same as before
539
13.9k
        if (need_bit) {
540
            if constexpr (sizeof(T) <= 4) {
541
                *output |= static_cast<T>(static_cast<uint32_t>(
542
                        (s >> (valid_bit - need_bit)) & ((static_cast<U>(1) << need_bit) - 1)));
543
10.2k
            } else {
544
10.2k
                *output |= static_cast<T>((s >> (valid_bit - need_bit)) &
545
10.2k
                                          ((static_cast<U>(1) << need_bit) - 1));
546
10.2k
            }
547
10.2k
            output++;
548
10.2k
            valid_bit -= need_bit;
549
10.2k
        }
550
551
13.9k
        int num = valid_bit / bit_width; // How many outputs can be processed at a time
552
553
        // same as before
554
61.3k
        for (int j = 0; j < num; j++) {
555
47.3k
            *output = static_cast<T>((s >> (((num - j - 1) * bit_width))) & output_mask);
556
47.3k
            output++;
557
47.3k
        }
558
13.9k
    }
559
24.6k
}
_ZN5doris10ForDecoderIlE19bit_unpack_optimizeInEEvPKhhiPl
Line
Count
Source
437
24.3k
                                        T* output) {
438
24.3k
    static_assert(std::is_same<U, int64_t>::value || std::is_same<U, __int128_t>::value,
439
24.3k
                  "bit_unpack_optimize only supports U = int64_t or __int128_t");
440
24.3k
    constexpr int u_size = sizeof(U);                   // Size of U
441
24.3k
    constexpr int u_size_shift = (u_size == 8) ? 3 : 4; // log2(u_size)
442
24.3k
    int valid_bit = 0;                                  // How many valid bits
443
24.3k
    int need_bit = 0;                                   // still need
444
24.3k
    size_t input_size = (in_num * bit_width + 7) >> 3;  // input's size
445
24.3k
    int full_batch_size =
446
24.3k
            cast_set<int>((input_size >> u_size_shift)
447
24.3k
                          << u_size_shift);     // Adjust input_size to a multiple of u_size
448
24.3k
    int tail_count = input_size & (u_size - 1); // The remainder of input_size modulo u_size.
449
    // The number of bits in input to adjust to multiples of 8 and thus more
450
24.3k
    int more_bit = cast_set<int>((input_size << 3) - (in_num * bit_width));
451
452
    // to ensure that only bit_width bits are valid
453
24.3k
    T output_mask;
454
24.3k
    if (bit_width >= static_cast<int>(sizeof(T) * 8)) {
455
0
        output_mask = static_cast<T>(~T(0));
456
24.3k
    } else {
457
24.3k
        output_mask = static_cast<T>((static_cast<T>(1) << bit_width) - 1);
458
24.3k
    }
459
460
24.3k
    U s = 0; // Temporary buffer for bitstream: aggregates input bytes into a large integer for unpacking
461
462
807k
    for (int i = 0; i < full_batch_size; i += u_size) {
463
783k
        s = 0;
464
465
783k
        s = to_endian<std::endian::big>(*((U*)(input + i)));
466
467
        // Determine what the valid bits are based on u_size
468
783k
        valid_bit = u_size << 3;
469
470
        // If input_size is exactly a multiple of 8, then need to remove the last more_bit in the last loop.
471
783k
        if (tail_count == 0 && i == full_batch_size - u_size) {
472
9.10k
            valid_bit -= more_bit;
473
9.10k
            s >>= more_bit;
474
9.10k
        }
475
476
783k
        if (need_bit) {
477
            // The last time we take away the high bit_width - need_bit,
478
            // we need to make up the rest of the need_bit from the width.
479
            // Use valid_bit - need_bit to compute high need_bit bits of s
480
            // perform an AND operation to ensure that only need_bit bits are valid
481
735k
            auto mask = (static_cast<U>(1) << need_bit) - 1;
482
735k
            auto shifted = s >> (valid_bit - need_bit);
483
735k
            auto masked_result = shifted & mask;
484
            if constexpr (sizeof(T) <= 4) {
485
                *output |= static_cast<T>(static_cast<uint32_t>(masked_result));
486
735k
            } else {
487
735k
                *output |= static_cast<T>(masked_result);
488
735k
            }
489
735k
            output++;
490
735k
            valid_bit -= need_bit;
491
735k
        }
492
493
783k
        int num = valid_bit / bit_width;             // How many outputs can be processed at a time
494
783k
        int remainder = valid_bit - num * bit_width; // How many bits are left to store
495
496
        // Starting with the highest valid bit, take out bit_width bits in sequence
497
        // perform an AND operation with output_mask to ensure that only bit_width bits are valid
498
        // (num-j-1) * bit_width used to calculate how many bits need to be removed at the end
499
        // But since there are still remainder bits that can't be processed, need to add the remainder
500
2.10M
        for (int j = 0; j < num; j++) {
501
1.32M
            *output =
502
1.32M
                    static_cast<T>((s >> (((num - j - 1) * bit_width) + remainder)) & output_mask);
503
1.32M
            output++;
504
1.32M
        }
505
506
783k
        if (remainder) {
507
            // Process the last remaining remainder bit.
508
            // y = (s & ((static_cast<U>(1) << remainder) - 1)) extract the last remainder bits.
509
            // output = y << (bit_width - remainder) Use the high bit_width - remainder bit
510
            if constexpr (sizeof(T) <= 4) {
511
                auto masked_value = static_cast<T>(
512
                        static_cast<uint32_t>(s & ((static_cast<U>(1) << remainder) - 1)));
513
                *output = static_cast<T>(masked_value << (bit_width - remainder));
514
749k
            } else {
515
749k
                auto masked_value = static_cast<T>((s & ((static_cast<U>(1) << remainder) - 1)));
516
749k
                *output = static_cast<T>(masked_value << (bit_width - remainder));
517
749k
            }
518
            // Already have remainder bits, next time need bit_width - remainder bits
519
749k
            need_bit = bit_width - remainder;
520
749k
        } else {
521
33.9k
            need_bit = 0;
522
33.9k
        }
523
783k
    }
524
525
    // remainder
526
24.3k
    if (tail_count) {
527
        // Put the tail_count numbers in the input into s in order, each number occupies 8 bit
528
137k
        for (int i = 0; i < tail_count; i++) {
529
121k
            s <<= 8;
530
121k
            s |= input[full_batch_size + i];
531
121k
        }
532
533
        // tail * 8 is the number of bits that are left to process
534
        // tail * 8 - more_bit is to remove the last more_bit
535
15.2k
        valid_bit = (tail_count << 3) - more_bit;
536
15.2k
        s >>= more_bit;
537
538
        // same as before
539
15.2k
        if (need_bit) {
540
            if constexpr (sizeof(T) <= 4) {
541
                *output |= static_cast<T>(static_cast<uint32_t>(
542
                        (s >> (valid_bit - need_bit)) & ((static_cast<U>(1) << need_bit) - 1)));
543
14.6k
            } else {
544
14.6k
                *output |= static_cast<T>((s >> (valid_bit - need_bit)) &
545
14.6k
                                          ((static_cast<U>(1) << need_bit) - 1));
546
14.6k
            }
547
14.6k
            output++;
548
14.6k
            valid_bit -= need_bit;
549
14.6k
        }
550
551
15.2k
        int num = valid_bit / bit_width; // How many outputs can be processed at a time
552
553
        // same as before
554
28.2k
        for (int j = 0; j < num; j++) {
555
13.0k
            *output = static_cast<T>((s >> (((num - j - 1) * bit_width))) & output_mask);
556
13.0k
            output++;
557
13.0k
        }
558
15.2k
    }
559
24.3k
}
_ZN5doris10ForDecoderInE19bit_unpack_optimizeIlEEvPKhhiPn
Line
Count
Source
437
16.5k
                                        T* output) {
438
16.5k
    static_assert(std::is_same<U, int64_t>::value || std::is_same<U, __int128_t>::value,
439
16.5k
                  "bit_unpack_optimize only supports U = int64_t or __int128_t");
440
16.5k
    constexpr int u_size = sizeof(U);                   // Size of U
441
16.5k
    constexpr int u_size_shift = (u_size == 8) ? 3 : 4; // log2(u_size)
442
16.5k
    int valid_bit = 0;                                  // How many valid bits
443
16.5k
    int need_bit = 0;                                   // still need
444
16.5k
    size_t input_size = (in_num * bit_width + 7) >> 3;  // input's size
445
16.5k
    int full_batch_size =
446
16.5k
            cast_set<int>((input_size >> u_size_shift)
447
16.5k
                          << u_size_shift);     // Adjust input_size to a multiple of u_size
448
16.5k
    int tail_count = input_size & (u_size - 1); // The remainder of input_size modulo u_size.
449
    // The number of bits in input to adjust to multiples of 8 and thus more
450
16.5k
    int more_bit = cast_set<int>((input_size << 3) - (in_num * bit_width));
451
452
    // to ensure that only bit_width bits are valid
453
16.5k
    T output_mask;
454
16.5k
    if (bit_width >= static_cast<int>(sizeof(T) * 8)) {
455
0
        output_mask = static_cast<T>(~T(0));
456
16.5k
    } else {
457
16.5k
        output_mask = static_cast<T>((static_cast<T>(1) << bit_width) - 1);
458
16.5k
    }
459
460
16.5k
    U s = 0; // Temporary buffer for bitstream: aggregates input bytes into a large integer for unpacking
461
462
548k
    for (int i = 0; i < full_batch_size; i += u_size) {
463
532k
        s = 0;
464
465
532k
        s = to_endian<std::endian::big>(*((U*)(input + i)));
466
467
        // Determine what the valid bits are based on u_size
468
532k
        valid_bit = u_size << 3;
469
470
        // If input_size is exactly a multiple of 8, then need to remove the last more_bit in the last loop.
471
532k
        if (tail_count == 0 && i == full_batch_size - u_size) {
472
2.24k
            valid_bit -= more_bit;
473
2.24k
            s >>= more_bit;
474
2.24k
        }
475
476
532k
        if (need_bit) {
477
            // The last time we take away the high bit_width - need_bit,
478
            // we need to make up the rest of the need_bit from the width.
479
            // Use valid_bit - need_bit to compute high need_bit bits of s
480
            // perform an AND operation to ensure that only need_bit bits are valid
481
414k
            auto mask = (static_cast<U>(1) << need_bit) - 1;
482
414k
            auto shifted = s >> (valid_bit - need_bit);
483
414k
            auto masked_result = shifted & mask;
484
            if constexpr (sizeof(T) <= 4) {
485
                *output |= static_cast<T>(static_cast<uint32_t>(masked_result));
486
414k
            } else {
487
414k
                *output |= static_cast<T>(masked_result);
488
414k
            }
489
414k
            output++;
490
414k
            valid_bit -= need_bit;
491
414k
        }
492
493
532k
        int num = valid_bit / bit_width;             // How many outputs can be processed at a time
494
532k
        int remainder = valid_bit - num * bit_width; // How many bits are left to store
495
496
        // Starting with the highest valid bit, take out bit_width bits in sequence
497
        // perform an AND operation with output_mask to ensure that only bit_width bits are valid
498
        // (num-j-1) * bit_width used to calculate how many bits need to be removed at the end
499
        // But since there are still remainder bits that can't be processed, need to add the remainder
500
2.14M
        for (int j = 0; j < num; j++) {
501
1.61M
            *output =
502
1.61M
                    static_cast<T>((s >> (((num - j - 1) * bit_width) + remainder)) & output_mask);
503
1.61M
            output++;
504
1.61M
        }
505
506
532k
        if (remainder) {
507
            // Process the last remaining remainder bit.
508
            // y = (s & ((static_cast<U>(1) << remainder) - 1)) extract the last remainder bits.
509
            // output = y << (bit_width - remainder) Use the high bit_width - remainder bit
510
            if constexpr (sizeof(T) <= 4) {
511
                auto masked_value = static_cast<T>(
512
                        static_cast<uint32_t>(s & ((static_cast<U>(1) << remainder) - 1)));
513
                *output = static_cast<T>(masked_value << (bit_width - remainder));
514
424k
            } else {
515
424k
                auto masked_value = static_cast<T>((s & ((static_cast<U>(1) << remainder) - 1)));
516
424k
                *output = static_cast<T>(masked_value << (bit_width - remainder));
517
424k
            }
518
            // Already have remainder bits, next time need bit_width - remainder bits
519
424k
            need_bit = bit_width - remainder;
520
424k
        } else {
521
107k
            need_bit = 0;
522
107k
        }
523
532k
    }
524
525
    // remainder
526
16.5k
    if (tail_count) {
527
        // Put the tail_count numbers in the input into s in order, each number occupies 8 bit
528
70.4k
        for (int i = 0; i < tail_count; i++) {
529
56.3k
            s <<= 8;
530
56.3k
            s |= input[full_batch_size + i];
531
56.3k
        }
532
533
        // tail * 8 is the number of bits that are left to process
534
        // tail * 8 - more_bit is to remove the last more_bit
535
14.0k
        valid_bit = (tail_count << 3) - more_bit;
536
14.0k
        s >>= more_bit;
537
538
        // same as before
539
14.0k
        if (need_bit) {
540
            if constexpr (sizeof(T) <= 4) {
541
                *output |= static_cast<T>(static_cast<uint32_t>(
542
                        (s >> (valid_bit - need_bit)) & ((static_cast<U>(1) << need_bit) - 1)));
543
10.2k
            } else {
544
10.2k
                *output |= static_cast<T>((s >> (valid_bit - need_bit)) &
545
10.2k
                                          ((static_cast<U>(1) << need_bit) - 1));
546
10.2k
            }
547
10.2k
            output++;
548
10.2k
            valid_bit -= need_bit;
549
10.2k
        }
550
551
14.0k
        int num = valid_bit / bit_width; // How many outputs can be processed at a time
552
553
        // same as before
554
61.5k
        for (int j = 0; j < num; j++) {
555
47.4k
            *output = static_cast<T>((s >> (((num - j - 1) * bit_width))) & output_mask);
556
47.4k
            output++;
557
47.4k
        }
558
14.0k
    }
559
16.5k
}
_ZN5doris10ForDecoderInE19bit_unpack_optimizeInEEvPKhhiPn
Line
Count
Source
437
97.0k
                                        T* output) {
438
97.0k
    static_assert(std::is_same<U, int64_t>::value || std::is_same<U, __int128_t>::value,
439
97.0k
                  "bit_unpack_optimize only supports U = int64_t or __int128_t");
440
97.0k
    constexpr int u_size = sizeof(U);                   // Size of U
441
97.0k
    constexpr int u_size_shift = (u_size == 8) ? 3 : 4; // log2(u_size)
442
97.0k
    int valid_bit = 0;                                  // How many valid bits
443
97.0k
    int need_bit = 0;                                   // still need
444
97.0k
    size_t input_size = (in_num * bit_width + 7) >> 3;  // input's size
445
97.0k
    int full_batch_size =
446
97.0k
            cast_set<int>((input_size >> u_size_shift)
447
97.0k
                          << u_size_shift);     // Adjust input_size to a multiple of u_size
448
97.0k
    int tail_count = input_size & (u_size - 1); // The remainder of input_size modulo u_size.
449
    // The number of bits in input to adjust to multiples of 8 and thus more
450
97.0k
    int more_bit = cast_set<int>((input_size << 3) - (in_num * bit_width));
451
452
    // to ensure that only bit_width bits are valid
453
97.0k
    T output_mask;
454
97.0k
    if (bit_width >= static_cast<int>(sizeof(T) * 8)) {
455
0
        output_mask = static_cast<T>(~T(0));
456
97.0k
    } else {
457
97.0k
        output_mask = static_cast<T>((static_cast<T>(1) << bit_width) - 1);
458
97.0k
    }
459
460
97.0k
    U s = 0; // Temporary buffer for bitstream: aggregates input bytes into a large integer for unpacking
461
462
7.05M
    for (int i = 0; i < full_batch_size; i += u_size) {
463
6.95M
        s = 0;
464
465
6.95M
        s = to_endian<std::endian::big>(*((U*)(input + i)));
466
467
        // Determine what the valid bits are based on u_size
468
6.95M
        valid_bit = u_size << 3;
469
470
        // If input_size is exactly a multiple of 8, then need to remove the last more_bit in the last loop.
471
6.95M
        if (tail_count == 0 && i == full_batch_size - u_size) {
472
21.7k
            valid_bit -= more_bit;
473
21.7k
            s >>= more_bit;
474
21.7k
        }
475
476
6.95M
        if (need_bit) {
477
            // The last time we take away the high bit_width - need_bit,
478
            // we need to make up the rest of the need_bit from the width.
479
            // Use valid_bit - need_bit to compute high need_bit bits of s
480
            // perform an AND operation to ensure that only need_bit bits are valid
481
6.61M
            auto mask = (static_cast<U>(1) << need_bit) - 1;
482
6.61M
            auto shifted = s >> (valid_bit - need_bit);
483
6.61M
            auto masked_result = shifted & mask;
484
            if constexpr (sizeof(T) <= 4) {
485
                *output |= static_cast<T>(static_cast<uint32_t>(masked_result));
486
6.61M
            } else {
487
6.61M
                *output |= static_cast<T>(masked_result);
488
6.61M
            }
489
6.61M
            output++;
490
6.61M
            valid_bit -= need_bit;
491
6.61M
        }
492
493
6.95M
        int num = valid_bit / bit_width;             // How many outputs can be processed at a time
494
6.95M
        int remainder = valid_bit - num * bit_width; // How many bits are left to store
495
496
        // Starting with the highest valid bit, take out bit_width bits in sequence
497
        // perform an AND operation with output_mask to ensure that only bit_width bits are valid
498
        // (num-j-1) * bit_width used to calculate how many bits need to be removed at the end
499
        // But since there are still remainder bits that can't be processed, need to add the remainder
500
10.6M
        for (int j = 0; j < num; j++) {
501
3.66M
            *output =
502
3.66M
                    static_cast<T>((s >> (((num - j - 1) * bit_width) + remainder)) & output_mask);
503
3.66M
            output++;
504
3.66M
        }
505
506
6.95M
        if (remainder) {
507
            // Process the last remaining remainder bit.
508
            // y = (s & ((static_cast<U>(1) << remainder) - 1)) extract the last remainder bits.
509
            // output = y << (bit_width - remainder) Use the high bit_width - remainder bit
510
            if constexpr (sizeof(T) <= 4) {
511
                auto masked_value = static_cast<T>(
512
                        static_cast<uint32_t>(s & ((static_cast<U>(1) << remainder) - 1)));
513
                *output = static_cast<T>(masked_value << (bit_width - remainder));
514
6.69M
            } else {
515
6.69M
                auto masked_value = static_cast<T>((s & ((static_cast<U>(1) << remainder) - 1)));
516
6.69M
                *output = static_cast<T>(masked_value << (bit_width - remainder));
517
6.69M
            }
518
            // Already have remainder bits, next time need bit_width - remainder bits
519
6.69M
            need_bit = bit_width - remainder;
520
6.69M
        } else {
521
265k
            need_bit = 0;
522
265k
        }
523
6.95M
    }
524
525
    // remainder
526
97.0k
    if (tail_count) {
527
        // Put the tail_count numbers in the input into s in order, each number occupies 8 bit
528
676k
        for (int i = 0; i < tail_count; i++) {
529
601k
            s <<= 8;
530
601k
            s |= input[full_batch_size + i];
531
601k
        }
532
533
        // tail * 8 is the number of bits that are left to process
534
        // tail * 8 - more_bit is to remove the last more_bit
535
75.2k
        valid_bit = (tail_count << 3) - more_bit;
536
75.2k
        s >>= more_bit;
537
538
        // same as before
539
75.2k
        if (need_bit) {
540
            if constexpr (sizeof(T) <= 4) {
541
                *output |= static_cast<T>(static_cast<uint32_t>(
542
                        (s >> (valid_bit - need_bit)) & ((static_cast<U>(1) << need_bit) - 1)));
543
72.8k
            } else {
544
72.8k
                *output |= static_cast<T>((s >> (valid_bit - need_bit)) &
545
72.8k
                                          ((static_cast<U>(1) << need_bit) - 1));
546
72.8k
            }
547
72.8k
            output++;
548
72.8k
            valid_bit -= need_bit;
549
72.8k
        }
550
551
75.2k
        int num = valid_bit / bit_width; // How many outputs can be processed at a time
552
553
        // same as before
554
101k
        for (int j = 0; j < num; j++) {
555
26.6k
            *output = static_cast<T>((s >> (((num - j - 1) * bit_width))) & output_mask);
556
26.6k
            output++;
557
26.6k
        }
558
75.2k
    }
559
97.0k
}
Unexecuted instantiation: _ZN5doris10ForDecoderIhE19bit_unpack_optimizeIlEEvPKhhiPh
Unexecuted instantiation: _ZN5doris10ForDecoderIhE19bit_unpack_optimizeInEEvPKhhiPh
Unexecuted instantiation: _ZN5doris10ForDecoderItE19bit_unpack_optimizeIlEEvPKhhiPt
Unexecuted instantiation: _ZN5doris10ForDecoderItE19bit_unpack_optimizeInEEvPKhhiPt
_ZN5doris10ForDecoderIjE19bit_unpack_optimizeIlEEvPKhhiPj
Line
Count
Source
437
10
                                        T* output) {
438
10
    static_assert(std::is_same<U, int64_t>::value || std::is_same<U, __int128_t>::value,
439
10
                  "bit_unpack_optimize only supports U = int64_t or __int128_t");
440
10
    constexpr int u_size = sizeof(U);                   // Size of U
441
10
    constexpr int u_size_shift = (u_size == 8) ? 3 : 4; // log2(u_size)
442
10
    int valid_bit = 0;                                  // How many valid bits
443
10
    int need_bit = 0;                                   // still need
444
10
    size_t input_size = (in_num * bit_width + 7) >> 3;  // input's size
445
10
    int full_batch_size =
446
10
            cast_set<int>((input_size >> u_size_shift)
447
10
                          << u_size_shift);     // Adjust input_size to a multiple of u_size
448
10
    int tail_count = input_size & (u_size - 1); // The remainder of input_size modulo u_size.
449
    // The number of bits in input to adjust to multiples of 8 and thus more
450
10
    int more_bit = cast_set<int>((input_size << 3) - (in_num * bit_width));
451
452
    // to ensure that only bit_width bits are valid
453
10
    T output_mask;
454
10
    if (bit_width >= static_cast<int>(sizeof(T) * 8)) {
455
0
        output_mask = static_cast<T>(~T(0));
456
10
    } else {
457
10
        output_mask = static_cast<T>((static_cast<T>(1) << bit_width) - 1);
458
10
    }
459
460
10
    U s = 0; // Temporary buffer for bitstream: aggregates input bytes into a large integer for unpacking
461
462
30
    for (int i = 0; i < full_batch_size; i += u_size) {
463
20
        s = 0;
464
465
20
        s = to_endian<std::endian::big>(*((U*)(input + i)));
466
467
        // Determine what the valid bits are based on u_size
468
20
        valid_bit = u_size << 3;
469
470
        // If input_size is exactly a multiple of 8, then need to remove the last more_bit in the last loop.
471
20
        if (tail_count == 0 && i == full_batch_size - u_size) {
472
10
            valid_bit -= more_bit;
473
10
            s >>= more_bit;
474
10
        }
475
476
20
        if (need_bit) {
477
            // The last time we take away the high bit_width - need_bit,
478
            // we need to make up the rest of the need_bit from the width.
479
            // Use valid_bit - need_bit to compute high need_bit bits of s
480
            // perform an AND operation to ensure that only need_bit bits are valid
481
0
            auto mask = (static_cast<U>(1) << need_bit) - 1;
482
0
            auto shifted = s >> (valid_bit - need_bit);
483
0
            auto masked_result = shifted & mask;
484
0
            if constexpr (sizeof(T) <= 4) {
485
0
                *output |= static_cast<T>(static_cast<uint32_t>(masked_result));
486
            } else {
487
                *output |= static_cast<T>(masked_result);
488
            }
489
0
            output++;
490
0
            valid_bit -= need_bit;
491
0
        }
492
493
20
        int num = valid_bit / bit_width;             // How many outputs can be processed at a time
494
20
        int remainder = valid_bit - num * bit_width; // How many bits are left to store
495
496
        // Starting with the highest valid bit, take out bit_width bits in sequence
497
        // perform an AND operation with output_mask to ensure that only bit_width bits are valid
498
        // (num-j-1) * bit_width used to calculate how many bits need to be removed at the end
499
        // But since there are still remainder bits that can't be processed, need to add the remainder
500
1.30k
        for (int j = 0; j < num; j++) {
501
1.28k
            *output =
502
1.28k
                    static_cast<T>((s >> (((num - j - 1) * bit_width) + remainder)) & output_mask);
503
1.28k
            output++;
504
1.28k
        }
505
506
20
        if (remainder) {
507
            // Process the last remaining remainder bit.
508
            // y = (s & ((static_cast<U>(1) << remainder) - 1)) extract the last remainder bits.
509
            // output = y << (bit_width - remainder) Use the high bit_width - remainder bit
510
0
            if constexpr (sizeof(T) <= 4) {
511
0
                auto masked_value = static_cast<T>(
512
0
                        static_cast<uint32_t>(s & ((static_cast<U>(1) << remainder) - 1)));
513
0
                *output = static_cast<T>(masked_value << (bit_width - remainder));
514
            } else {
515
                auto masked_value = static_cast<T>((s & ((static_cast<U>(1) << remainder) - 1)));
516
                *output = static_cast<T>(masked_value << (bit_width - remainder));
517
            }
518
            // Already have remainder bits, next time need bit_width - remainder bits
519
0
            need_bit = bit_width - remainder;
520
20
        } else {
521
20
            need_bit = 0;
522
20
        }
523
20
    }
524
525
    // remainder
526
10
    if (tail_count) {
527
        // Put the tail_count numbers in the input into s in order, each number occupies 8 bit
528
0
        for (int i = 0; i < tail_count; i++) {
529
0
            s <<= 8;
530
0
            s |= input[full_batch_size + i];
531
0
        }
532
533
        // tail * 8 is the number of bits that are left to process
534
        // tail * 8 - more_bit is to remove the last more_bit
535
0
        valid_bit = (tail_count << 3) - more_bit;
536
0
        s >>= more_bit;
537
538
        // same as before
539
0
        if (need_bit) {
540
0
            if constexpr (sizeof(T) <= 4) {
541
0
                *output |= static_cast<T>(static_cast<uint32_t>(
542
0
                        (s >> (valid_bit - need_bit)) & ((static_cast<U>(1) << need_bit) - 1)));
543
            } else {
544
                *output |= static_cast<T>((s >> (valid_bit - need_bit)) &
545
                                          ((static_cast<U>(1) << need_bit) - 1));
546
            }
547
0
            output++;
548
0
            valid_bit -= need_bit;
549
0
        }
550
551
0
        int num = valid_bit / bit_width; // How many outputs can be processed at a time
552
553
        // same as before
554
0
        for (int j = 0; j < num; j++) {
555
0
            *output = static_cast<T>((s >> (((num - j - 1) * bit_width))) & output_mask);
556
0
            output++;
557
0
        }
558
0
    }
559
10
}
Unexecuted instantiation: _ZN5doris10ForDecoderIjE19bit_unpack_optimizeInEEvPKhhiPj
Unexecuted instantiation: _ZN5doris10ForDecoderImE19bit_unpack_optimizeIlEEvPKhhiPm
Unexecuted instantiation: _ZN5doris10ForDecoderImE19bit_unpack_optimizeInEEvPKhhiPm
Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE19bit_unpack_optimizeIlEEvPKhhiPS1_
Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE19bit_unpack_optimizeInEEvPKhhiPS1_
Unexecuted instantiation: _ZN5doris10ForDecoderIoE19bit_unpack_optimizeIlEEvPKhhiPo
Unexecuted instantiation: _ZN5doris10ForDecoderIoE19bit_unpack_optimizeInEEvPKhhiPo
560
561
// The reverse of bit_pack method, get original integer data list from packed bits
562
// param[in] input: the packed bits need to unpack
563
// param[in] in_num: the integer number in packed bits
564
// param[in] bit_width: how many bit we used to store each integer data
565
// param[out] output: the original integer data list
566
template <typename T>
567
162k
void ForDecoder<T>::bit_unpack(const uint8_t* input, uint8_t in_num, int bit_width, T* output) {
568
    /*
569
        When 32 < bit_width <= 64 unrolling the loop 16 times is more efficient than unrolling it 8 times.
570
        When bit_width > 64, we must use __int128_t and unroll the loop 16 times.
571
    */
572
162k
    if (bit_width <= 32) {
573
41.2k
        bit_unpack_optimize<int64_t>(input, in_num, bit_width, output);
574
121k
    } else {
575
121k
        bit_unpack_optimize<__int128_t>(input, in_num, bit_width, output);
576
121k
    }
577
162k
}
Unexecuted instantiation: _ZN5doris10ForDecoderIaE10bit_unpackEPKhhiPa
Unexecuted instantiation: _ZN5doris10ForDecoderIsE10bit_unpackEPKhhiPs
_ZN5doris10ForDecoderIiE10bit_unpackEPKhhiPi
Line
Count
Source
567
18
void ForDecoder<T>::bit_unpack(const uint8_t* input, uint8_t in_num, int bit_width, T* output) {
568
    /*
569
        When 32 < bit_width <= 64 unrolling the loop 16 times is more efficient than unrolling it 8 times.
570
        When bit_width > 64, we must use __int128_t and unroll the loop 16 times.
571
    */
572
18
    if (bit_width <= 32) {
573
18
        bit_unpack_optimize<int64_t>(input, in_num, bit_width, output);
574
18
    } else {
575
0
        bit_unpack_optimize<__int128_t>(input, in_num, bit_width, output);
576
0
    }
577
18
}
_ZN5doris10ForDecoderIlE10bit_unpackEPKhhiPl
Line
Count
Source
567
48.9k
void ForDecoder<T>::bit_unpack(const uint8_t* input, uint8_t in_num, int bit_width, T* output) {
568
    /*
569
        When 32 < bit_width <= 64 unrolling the loop 16 times is more efficient than unrolling it 8 times.
570
        When bit_width > 64, we must use __int128_t and unroll the loop 16 times.
571
    */
572
48.9k
    if (bit_width <= 32) {
573
24.6k
        bit_unpack_optimize<int64_t>(input, in_num, bit_width, output);
574
24.6k
    } else {
575
24.3k
        bit_unpack_optimize<__int128_t>(input, in_num, bit_width, output);
576
24.3k
    }
577
48.9k
}
_ZN5doris10ForDecoderInE10bit_unpackEPKhhiPn
Line
Count
Source
567
113k
void ForDecoder<T>::bit_unpack(const uint8_t* input, uint8_t in_num, int bit_width, T* output) {
568
    /*
569
        When 32 < bit_width <= 64 unrolling the loop 16 times is more efficient than unrolling it 8 times.
570
        When bit_width > 64, we must use __int128_t and unroll the loop 16 times.
571
    */
572
113k
    if (bit_width <= 32) {
573
16.5k
        bit_unpack_optimize<int64_t>(input, in_num, bit_width, output);
574
97.0k
    } else {
575
97.0k
        bit_unpack_optimize<__int128_t>(input, in_num, bit_width, output);
576
97.0k
    }
577
113k
}
Unexecuted instantiation: _ZN5doris10ForDecoderIhE10bit_unpackEPKhhiPh
Unexecuted instantiation: _ZN5doris10ForDecoderItE10bit_unpackEPKhhiPt
_ZN5doris10ForDecoderIjE10bit_unpackEPKhhiPj
Line
Count
Source
567
10
void ForDecoder<T>::bit_unpack(const uint8_t* input, uint8_t in_num, int bit_width, T* output) {
568
    /*
569
        When 32 < bit_width <= 64 unrolling the loop 16 times is more efficient than unrolling it 8 times.
570
        When bit_width > 64, we must use __int128_t and unroll the loop 16 times.
571
    */
572
10
    if (bit_width <= 32) {
573
10
        bit_unpack_optimize<int64_t>(input, in_num, bit_width, output);
574
10
    } else {
575
0
        bit_unpack_optimize<__int128_t>(input, in_num, bit_width, output);
576
0
    }
577
10
}
Unexecuted instantiation: _ZN5doris10ForDecoderImE10bit_unpackEPKhhiPm
Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE10bit_unpackEPKhhiPS1_
Unexecuted instantiation: _ZN5doris10ForDecoderIoE10bit_unpackEPKhhiPo
578
579
template <typename T>
580
8.35M
void ForDecoder<T>::decode_current_frame(T* output) {
581
8.35M
    uint32_t frame_index = _current_index / _max_frame_size;
582
8.35M
    if (frame_index == _current_decoded_frame) {
583
8.25M
        return; // current frame already decoded
584
8.25M
    }
585
97.8k
    _current_decoded_frame = frame_index;
586
97.8k
    uint8_t current_frame_size = cast_set<uint8_t>(frame_size(frame_index));
587
588
97.8k
    uint32_t base_offset = _frame_offsets[_current_decoded_frame];
589
97.8k
    T min = 0;
590
97.8k
    uint32_t delta_offset = 0;
591
97.8k
    if constexpr (sizeof(T) == 16) {
592
48.8k
        min = static_cast<T>(decode_fixed128_le(_buffer + base_offset));
593
48.8k
        delta_offset = base_offset + 16;
594
48.9k
    } else if constexpr (sizeof(T) == 8) {
595
48.9k
        min = static_cast<T>(decode_fixed64_le(_buffer + base_offset));
596
48.9k
        delta_offset = base_offset + 8;
597
48.9k
    } else {
598
28
        min = static_cast<T>(decode_fixed32_le(_buffer + base_offset));
599
28
        delta_offset = base_offset + 4;
600
28
    }
601
602
97.8k
    uint8_t bit_width = _bit_widths[_current_decoded_frame];
603
604
97.8k
    bool is_original_value = _storage_formats[_current_decoded_frame] == 2;
605
97.8k
    if (is_original_value) {
606
0
        bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, output);
607
97.8k
    } else {
608
97.8k
        bool is_ascending = _storage_formats[_current_decoded_frame] == 1;
609
97.8k
        std::vector<T> delta_values(current_frame_size);
610
97.8k
        bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, delta_values.data());
611
97.8k
        if (is_ascending) {
612
902
            T pre_value = min;
613
7.74k
            for (uint8_t i = 0; i < current_frame_size; i++) {
614
6.84k
                T value = delta_values[i] + pre_value;
615
6.84k
                output[i] = value;
616
6.84k
                pre_value = value;
617
6.84k
            }
618
96.9k
        } else {
619
8.45M
            for (uint8_t i = 0; i < current_frame_size; i++) {
620
8.35M
                output[i] = delta_values[i] + min;
621
8.35M
            }
622
96.9k
        }
623
97.8k
    }
624
97.8k
}
Unexecuted instantiation: _ZN5doris10ForDecoderIaE20decode_current_frameEPa
Unexecuted instantiation: _ZN5doris10ForDecoderIsE20decode_current_frameEPs
_ZN5doris10ForDecoderIiE20decode_current_frameEPi
Line
Count
Source
580
20
void ForDecoder<T>::decode_current_frame(T* output) {
581
20
    uint32_t frame_index = _current_index / _max_frame_size;
582
20
    if (frame_index == _current_decoded_frame) {
583
2
        return; // current frame already decoded
584
2
    }
585
18
    _current_decoded_frame = frame_index;
586
18
    uint8_t current_frame_size = cast_set<uint8_t>(frame_size(frame_index));
587
588
18
    uint32_t base_offset = _frame_offsets[_current_decoded_frame];
589
18
    T min = 0;
590
18
    uint32_t delta_offset = 0;
591
    if constexpr (sizeof(T) == 16) {
592
        min = static_cast<T>(decode_fixed128_le(_buffer + base_offset));
593
        delta_offset = base_offset + 16;
594
    } else if constexpr (sizeof(T) == 8) {
595
        min = static_cast<T>(decode_fixed64_le(_buffer + base_offset));
596
        delta_offset = base_offset + 8;
597
18
    } else {
598
18
        min = static_cast<T>(decode_fixed32_le(_buffer + base_offset));
599
18
        delta_offset = base_offset + 4;
600
18
    }
601
602
18
    uint8_t bit_width = _bit_widths[_current_decoded_frame];
603
604
18
    bool is_original_value = _storage_formats[_current_decoded_frame] == 2;
605
18
    if (is_original_value) {
606
0
        bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, output);
607
18
    } else {
608
18
        bool is_ascending = _storage_formats[_current_decoded_frame] == 1;
609
18
        std::vector<T> delta_values(current_frame_size);
610
18
        bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, delta_values.data());
611
18
        if (is_ascending) {
612
18
            T pre_value = min;
613
1.56k
            for (uint8_t i = 0; i < current_frame_size; i++) {
614
1.54k
                T value = delta_values[i] + pre_value;
615
1.54k
                output[i] = value;
616
1.54k
                pre_value = value;
617
1.54k
            }
618
18
        } else {
619
0
            for (uint8_t i = 0; i < current_frame_size; i++) {
620
0
                output[i] = delta_values[i] + min;
621
0
            }
622
0
        }
623
18
    }
624
18
}
_ZN5doris10ForDecoderIlE20decode_current_frameEPl
Line
Count
Source
580
4.17M
void ForDecoder<T>::decode_current_frame(T* output) {
581
4.17M
    uint32_t frame_index = _current_index / _max_frame_size;
582
4.17M
    if (frame_index == _current_decoded_frame) {
583
4.12M
        return; // current frame already decoded
584
4.12M
    }
585
48.9k
    _current_decoded_frame = frame_index;
586
48.9k
    uint8_t current_frame_size = cast_set<uint8_t>(frame_size(frame_index));
587
588
48.9k
    uint32_t base_offset = _frame_offsets[_current_decoded_frame];
589
48.9k
    T min = 0;
590
48.9k
    uint32_t delta_offset = 0;
591
    if constexpr (sizeof(T) == 16) {
592
        min = static_cast<T>(decode_fixed128_le(_buffer + base_offset));
593
        delta_offset = base_offset + 16;
594
48.9k
    } else if constexpr (sizeof(T) == 8) {
595
48.9k
        min = static_cast<T>(decode_fixed64_le(_buffer + base_offset));
596
48.9k
        delta_offset = base_offset + 8;
597
    } else {
598
        min = static_cast<T>(decode_fixed32_le(_buffer + base_offset));
599
        delta_offset = base_offset + 4;
600
    }
601
602
48.9k
    uint8_t bit_width = _bit_widths[_current_decoded_frame];
603
604
48.9k
    bool is_original_value = _storage_formats[_current_decoded_frame] == 2;
605
48.9k
    if (is_original_value) {
606
0
        bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, output);
607
48.9k
    } else {
608
48.9k
        bool is_ascending = _storage_formats[_current_decoded_frame] == 1;
609
48.9k
        std::vector<T> delta_values(current_frame_size);
610
48.9k
        bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, delta_values.data());
611
48.9k
        if (is_ascending) {
612
446
            T pre_value = min;
613
3.79k
            for (uint8_t i = 0; i < current_frame_size; i++) {
614
3.34k
                T value = delta_values[i] + pre_value;
615
3.34k
                output[i] = value;
616
3.34k
                pre_value = value;
617
3.34k
            }
618
48.4k
        } else {
619
4.22M
            for (uint8_t i = 0; i < current_frame_size; i++) {
620
4.17M
                output[i] = delta_values[i] + min;
621
4.17M
            }
622
48.4k
        }
623
48.9k
    }
624
48.9k
}
_ZN5doris10ForDecoderInE20decode_current_frameEPn
Line
Count
Source
580
4.17M
void ForDecoder<T>::decode_current_frame(T* output) {
581
4.17M
    uint32_t frame_index = _current_index / _max_frame_size;
582
4.17M
    if (frame_index == _current_decoded_frame) {
583
4.12M
        return; // current frame already decoded
584
4.12M
    }
585
48.8k
    _current_decoded_frame = frame_index;
586
48.8k
    uint8_t current_frame_size = cast_set<uint8_t>(frame_size(frame_index));
587
588
48.8k
    uint32_t base_offset = _frame_offsets[_current_decoded_frame];
589
48.8k
    T min = 0;
590
48.8k
    uint32_t delta_offset = 0;
591
48.8k
    if constexpr (sizeof(T) == 16) {
592
48.8k
        min = static_cast<T>(decode_fixed128_le(_buffer + base_offset));
593
48.8k
        delta_offset = base_offset + 16;
594
    } else if constexpr (sizeof(T) == 8) {
595
        min = static_cast<T>(decode_fixed64_le(_buffer + base_offset));
596
        delta_offset = base_offset + 8;
597
    } else {
598
        min = static_cast<T>(decode_fixed32_le(_buffer + base_offset));
599
        delta_offset = base_offset + 4;
600
    }
601
602
48.8k
    uint8_t bit_width = _bit_widths[_current_decoded_frame];
603
604
48.8k
    bool is_original_value = _storage_formats[_current_decoded_frame] == 2;
605
48.8k
    if (is_original_value) {
606
0
        bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, output);
607
48.8k
    } else {
608
48.8k
        bool is_ascending = _storage_formats[_current_decoded_frame] == 1;
609
48.8k
        std::vector<T> delta_values(current_frame_size);
610
48.8k
        bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, delta_values.data());
611
48.8k
        if (is_ascending) {
612
428
            T pre_value = min;
613
1.10k
            for (uint8_t i = 0; i < current_frame_size; i++) {
614
676
                T value = delta_values[i] + pre_value;
615
676
                output[i] = value;
616
676
                pre_value = value;
617
676
            }
618
48.4k
        } else {
619
4.22M
            for (uint8_t i = 0; i < current_frame_size; i++) {
620
4.17M
                output[i] = delta_values[i] + min;
621
4.17M
            }
622
48.4k
        }
623
48.8k
    }
624
48.8k
}
Unexecuted instantiation: _ZN5doris10ForDecoderIhE20decode_current_frameEPh
Unexecuted instantiation: _ZN5doris10ForDecoderItE20decode_current_frameEPt
_ZN5doris10ForDecoderIjE20decode_current_frameEPj
Line
Count
Source
580
10
void ForDecoder<T>::decode_current_frame(T* output) {
581
10
    uint32_t frame_index = _current_index / _max_frame_size;
582
10
    if (frame_index == _current_decoded_frame) {
583
0
        return; // current frame already decoded
584
0
    }
585
10
    _current_decoded_frame = frame_index;
586
10
    uint8_t current_frame_size = cast_set<uint8_t>(frame_size(frame_index));
587
588
10
    uint32_t base_offset = _frame_offsets[_current_decoded_frame];
589
10
    T min = 0;
590
10
    uint32_t delta_offset = 0;
591
    if constexpr (sizeof(T) == 16) {
592
        min = static_cast<T>(decode_fixed128_le(_buffer + base_offset));
593
        delta_offset = base_offset + 16;
594
    } else if constexpr (sizeof(T) == 8) {
595
        min = static_cast<T>(decode_fixed64_le(_buffer + base_offset));
596
        delta_offset = base_offset + 8;
597
10
    } else {
598
10
        min = static_cast<T>(decode_fixed32_le(_buffer + base_offset));
599
10
        delta_offset = base_offset + 4;
600
10
    }
601
602
10
    uint8_t bit_width = _bit_widths[_current_decoded_frame];
603
604
10
    bool is_original_value = _storage_formats[_current_decoded_frame] == 2;
605
10
    if (is_original_value) {
606
0
        bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, output);
607
10
    } else {
608
10
        bool is_ascending = _storage_formats[_current_decoded_frame] == 1;
609
10
        std::vector<T> delta_values(current_frame_size);
610
10
        bit_unpack(_buffer + delta_offset, current_frame_size, bit_width, delta_values.data());
611
10
        if (is_ascending) {
612
10
            T pre_value = min;
613
1.29k
            for (uint8_t i = 0; i < current_frame_size; i++) {
614
1.28k
                T value = delta_values[i] + pre_value;
615
1.28k
                output[i] = value;
616
1.28k
                pre_value = value;
617
1.28k
            }
618
10
        } else {
619
0
            for (uint8_t i = 0; i < current_frame_size; i++) {
620
0
                output[i] = delta_values[i] + min;
621
0
            }
622
0
        }
623
10
    }
624
10
}
Unexecuted instantiation: _ZN5doris10ForDecoderImE20decode_current_frameEPm
Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE20decode_current_frameEPS1_
Unexecuted instantiation: _ZN5doris10ForDecoderIoE20decode_current_frameEPo
625
626
template <typename T>
627
24
T ForDecoder<T>::decode_frame_min_value(uint32_t frame_index) {
628
24
    uint32_t min_offset = _frame_offsets[frame_index];
629
24
    T min = 0;
630
24
    if constexpr (sizeof(T) == 16) {
631
0
        min = static_cast<T>(decode_fixed128_le(_buffer + min_offset));
632
24
    } else if constexpr (sizeof(T) == 8) {
633
24
        min = static_cast<T>(decode_fixed64_le(_buffer + min_offset));
634
24
    } else {
635
0
        min = static_cast<T>(decode_fixed32_le(_buffer + min_offset));
636
0
    }
637
24
    return min;
638
24
}
Unexecuted instantiation: _ZN5doris10ForDecoderIaE22decode_frame_min_valueEj
Unexecuted instantiation: _ZN5doris10ForDecoderIsE22decode_frame_min_valueEj
Unexecuted instantiation: _ZN5doris10ForDecoderIiE22decode_frame_min_valueEj
_ZN5doris10ForDecoderIlE22decode_frame_min_valueEj
Line
Count
Source
627
24
T ForDecoder<T>::decode_frame_min_value(uint32_t frame_index) {
628
24
    uint32_t min_offset = _frame_offsets[frame_index];
629
24
    T min = 0;
630
    if constexpr (sizeof(T) == 16) {
631
        min = static_cast<T>(decode_fixed128_le(_buffer + min_offset));
632
24
    } else if constexpr (sizeof(T) == 8) {
633
24
        min = static_cast<T>(decode_fixed64_le(_buffer + min_offset));
634
    } else {
635
        min = static_cast<T>(decode_fixed32_le(_buffer + min_offset));
636
    }
637
24
    return min;
638
24
}
Unexecuted instantiation: _ZN5doris10ForDecoderInE22decode_frame_min_valueEj
Unexecuted instantiation: _ZN5doris10ForDecoderIhE22decode_frame_min_valueEj
Unexecuted instantiation: _ZN5doris10ForDecoderItE22decode_frame_min_valueEj
Unexecuted instantiation: _ZN5doris10ForDecoderIjE22decode_frame_min_valueEj
Unexecuted instantiation: _ZN5doris10ForDecoderImE22decode_frame_min_valueEj
Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE22decode_frame_min_valueEj
Unexecuted instantiation: _ZN5doris10ForDecoderIoE22decode_frame_min_valueEj
639
640
template <typename T>
641
8.35M
T* ForDecoder<T>::copy_value(T* val, size_t count) {
642
8.35M
    memcpy(val, &_out_buffer[_current_index % _max_frame_size], sizeof(T) * count);
643
8.35M
    _current_index += count;
644
8.35M
    val += count;
645
8.35M
    return val;
646
8.35M
}
Unexecuted instantiation: _ZN5doris10ForDecoderIaE10copy_valueEPam
Unexecuted instantiation: _ZN5doris10ForDecoderIsE10copy_valueEPsm
_ZN5doris10ForDecoderIiE10copy_valueEPim
Line
Count
Source
641
16
T* ForDecoder<T>::copy_value(T* val, size_t count) {
642
16
    memcpy(val, &_out_buffer[_current_index % _max_frame_size], sizeof(T) * count);
643
16
    _current_index += count;
644
16
    val += count;
645
16
    return val;
646
16
}
_ZN5doris10ForDecoderIlE10copy_valueEPlm
Line
Count
Source
641
4.17M
T* ForDecoder<T>::copy_value(T* val, size_t count) {
642
4.17M
    memcpy(val, &_out_buffer[_current_index % _max_frame_size], sizeof(T) * count);
643
4.17M
    _current_index += count;
644
4.17M
    val += count;
645
4.17M
    return val;
646
4.17M
}
_ZN5doris10ForDecoderInE10copy_valueEPnm
Line
Count
Source
641
4.17M
T* ForDecoder<T>::copy_value(T* val, size_t count) {
642
4.17M
    memcpy(val, &_out_buffer[_current_index % _max_frame_size], sizeof(T) * count);
643
4.17M
    _current_index += count;
644
4.17M
    val += count;
645
4.17M
    return val;
646
4.17M
}
Unexecuted instantiation: _ZN5doris10ForDecoderIhE10copy_valueEPhm
Unexecuted instantiation: _ZN5doris10ForDecoderItE10copy_valueEPtm
_ZN5doris10ForDecoderIjE10copy_valueEPjm
Line
Count
Source
641
6
T* ForDecoder<T>::copy_value(T* val, size_t count) {
642
6
    memcpy(val, &_out_buffer[_current_index % _max_frame_size], sizeof(T) * count);
643
6
    _current_index += count;
644
6
    val += count;
645
6
    return val;
646
6
}
Unexecuted instantiation: _ZN5doris10ForDecoderImE10copy_valueEPmm
Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE10copy_valueEPS1_m
Unexecuted instantiation: _ZN5doris10ForDecoderIoE10copy_valueEPom
647
648
template <typename T>
649
8.35M
bool ForDecoder<T>::get_batch(T* val, size_t count) {
650
8.35M
    if (_current_index + count > _values_num) {
651
2
        return false;
652
2
    }
653
654
8.35M
    decode_current_frame(_out_buffer.data());
655
656
8.35M
    if (_current_index + count < _max_frame_size * (_current_decoded_frame + 1)) {
657
8.32M
        copy_value(val, count);
658
8.32M
        return true;
659
8.32M
    }
660
661
    // 1. padding one frame
662
32.7k
    size_t padding_num = _max_frame_size * (_current_decoded_frame + 1) - _current_index;
663
32.7k
    val = copy_value(val, padding_num);
664
665
    // 2. process frame by frame
666
32.7k
    size_t frame_count = (count - padding_num) / _max_frame_size;
667
32.8k
    for (size_t i = 0; i < frame_count; i++) {
668
        // directly decode value to the output, don't  buffer the value
669
14
        decode_current_frame(val);
670
14
        _current_index += _max_frame_size;
671
14
        val += _max_frame_size;
672
14
    }
673
674
    // 3. process remaining value
675
32.7k
    size_t remaining_num = (count - padding_num) % _max_frame_size;
676
32.7k
    if (remaining_num > 0) {
677
8
        decode_current_frame(_out_buffer.data());
678
8
        val = copy_value(val, remaining_num);
679
8
    }
680
681
32.7k
    return true;
682
8.35M
}
Unexecuted instantiation: _ZN5doris10ForDecoderIaE9get_batchEPam
Unexecuted instantiation: _ZN5doris10ForDecoderIsE9get_batchEPsm
_ZN5doris10ForDecoderIiE9get_batchEPim
Line
Count
Source
649
16
bool ForDecoder<T>::get_batch(T* val, size_t count) {
650
16
    if (_current_index + count > _values_num) {
651
2
        return false;
652
2
    }
653
654
14
    decode_current_frame(_out_buffer.data());
655
656
14
    if (_current_index + count < _max_frame_size * (_current_decoded_frame + 1)) {
657
8
        copy_value(val, count);
658
8
        return true;
659
8
    }
660
661
    // 1. padding one frame
662
6
    size_t padding_num = _max_frame_size * (_current_decoded_frame + 1) - _current_index;
663
6
    val = copy_value(val, padding_num);
664
665
    // 2. process frame by frame
666
6
    size_t frame_count = (count - padding_num) / _max_frame_size;
667
10
    for (size_t i = 0; i < frame_count; i++) {
668
        // directly decode value to the output, don't  buffer the value
669
4
        decode_current_frame(val);
670
4
        _current_index += _max_frame_size;
671
4
        val += _max_frame_size;
672
4
    }
673
674
    // 3. process remaining value
675
6
    size_t remaining_num = (count - padding_num) % _max_frame_size;
676
6
    if (remaining_num > 0) {
677
2
        decode_current_frame(_out_buffer.data());
678
2
        val = copy_value(val, remaining_num);
679
2
    }
680
681
6
    return true;
682
14
}
_ZN5doris10ForDecoderIlE9get_batchEPlm
Line
Count
Source
649
4.17M
bool ForDecoder<T>::get_batch(T* val, size_t count) {
650
4.17M
    if (_current_index + count > _values_num) {
651
0
        return false;
652
0
    }
653
654
4.17M
    decode_current_frame(_out_buffer.data());
655
656
4.17M
    if (_current_index + count < _max_frame_size * (_current_decoded_frame + 1)) {
657
4.16M
        copy_value(val, count);
658
4.16M
        return true;
659
4.16M
    }
660
661
    // 1. padding one frame
662
16.3k
    size_t padding_num = _max_frame_size * (_current_decoded_frame + 1) - _current_index;
663
16.3k
    val = copy_value(val, padding_num);
664
665
    // 2. process frame by frame
666
16.3k
    size_t frame_count = (count - padding_num) / _max_frame_size;
667
16.3k
    for (size_t i = 0; i < frame_count; i++) {
668
        // directly decode value to the output, don't  buffer the value
669
6
        decode_current_frame(val);
670
6
        _current_index += _max_frame_size;
671
6
        val += _max_frame_size;
672
6
    }
673
674
    // 3. process remaining value
675
16.3k
    size_t remaining_num = (count - padding_num) % _max_frame_size;
676
16.3k
    if (remaining_num > 0) {
677
6
        decode_current_frame(_out_buffer.data());
678
6
        val = copy_value(val, remaining_num);
679
6
    }
680
681
16.3k
    return true;
682
4.17M
}
_ZN5doris10ForDecoderInE9get_batchEPnm
Line
Count
Source
649
4.17M
bool ForDecoder<T>::get_batch(T* val, size_t count) {
650
4.17M
    if (_current_index + count > _values_num) {
651
0
        return false;
652
0
    }
653
654
4.17M
    decode_current_frame(_out_buffer.data());
655
656
4.17M
    if (_current_index + count < _max_frame_size * (_current_decoded_frame + 1)) {
657
4.16M
        copy_value(val, count);
658
4.16M
        return true;
659
4.16M
    }
660
661
    // 1. padding one frame
662
16.3k
    size_t padding_num = _max_frame_size * (_current_decoded_frame + 1) - _current_index;
663
16.3k
    val = copy_value(val, padding_num);
664
665
    // 2. process frame by frame
666
16.3k
    size_t frame_count = (count - padding_num) / _max_frame_size;
667
16.3k
    for (size_t i = 0; i < frame_count; i++) {
668
        // directly decode value to the output, don't  buffer the value
669
0
        decode_current_frame(val);
670
0
        _current_index += _max_frame_size;
671
0
        val += _max_frame_size;
672
0
    }
673
674
    // 3. process remaining value
675
16.3k
    size_t remaining_num = (count - padding_num) % _max_frame_size;
676
16.3k
    if (remaining_num > 0) {
677
0
        decode_current_frame(_out_buffer.data());
678
0
        val = copy_value(val, remaining_num);
679
0
    }
680
681
16.3k
    return true;
682
4.17M
}
Unexecuted instantiation: _ZN5doris10ForDecoderIhE9get_batchEPhm
Unexecuted instantiation: _ZN5doris10ForDecoderItE9get_batchEPtm
_ZN5doris10ForDecoderIjE9get_batchEPjm
Line
Count
Source
649
6
bool ForDecoder<T>::get_batch(T* val, size_t count) {
650
6
    if (_current_index + count > _values_num) {
651
0
        return false;
652
0
    }
653
654
6
    decode_current_frame(_out_buffer.data());
655
656
6
    if (_current_index + count < _max_frame_size * (_current_decoded_frame + 1)) {
657
0
        copy_value(val, count);
658
0
        return true;
659
0
    }
660
661
    // 1. padding one frame
662
6
    size_t padding_num = _max_frame_size * (_current_decoded_frame + 1) - _current_index;
663
6
    val = copy_value(val, padding_num);
664
665
    // 2. process frame by frame
666
6
    size_t frame_count = (count - padding_num) / _max_frame_size;
667
10
    for (size_t i = 0; i < frame_count; i++) {
668
        // directly decode value to the output, don't  buffer the value
669
4
        decode_current_frame(val);
670
4
        _current_index += _max_frame_size;
671
4
        val += _max_frame_size;
672
4
    }
673
674
    // 3. process remaining value
675
6
    size_t remaining_num = (count - padding_num) % _max_frame_size;
676
6
    if (remaining_num > 0) {
677
0
        decode_current_frame(_out_buffer.data());
678
0
        val = copy_value(val, remaining_num);
679
0
    }
680
681
6
    return true;
682
6
}
Unexecuted instantiation: _ZN5doris10ForDecoderImE9get_batchEPmm
Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE9get_batchEPS1_m
Unexecuted instantiation: _ZN5doris10ForDecoderIoE9get_batchEPom
683
684
template <typename T>
685
6
bool ForDecoder<T>::skip(int32_t skip_num) {
686
6
    if (_current_index + skip_num >= _values_num) {
687
0
        return false;
688
0
    }
689
6
    _current_index = _current_index + skip_num;
690
6
    return true;
691
6
}
Unexecuted instantiation: _ZN5doris10ForDecoderIaE4skipEi
Unexecuted instantiation: _ZN5doris10ForDecoderIsE4skipEi
Unexecuted instantiation: _ZN5doris10ForDecoderIiE4skipEi
Unexecuted instantiation: _ZN5doris10ForDecoderIlE4skipEi
Unexecuted instantiation: _ZN5doris10ForDecoderInE4skipEi
Unexecuted instantiation: _ZN5doris10ForDecoderIhE4skipEi
Unexecuted instantiation: _ZN5doris10ForDecoderItE4skipEi
_ZN5doris10ForDecoderIjE4skipEi
Line
Count
Source
685
6
bool ForDecoder<T>::skip(int32_t skip_num) {
686
6
    if (_current_index + skip_num >= _values_num) {
687
0
        return false;
688
0
    }
689
6
    _current_index = _current_index + skip_num;
690
6
    return true;
691
6
}
Unexecuted instantiation: _ZN5doris10ForDecoderImE4skipEi
Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE4skipEi
Unexecuted instantiation: _ZN5doris10ForDecoderIoE4skipEi
692
693
template <typename T>
694
12
uint32_t ForDecoder<T>::seek_last_frame_before_value(T target) {
695
    // first of all, find the first frame >= target
696
12
    uint32_t left = 0;
697
12
    uint32_t right = _frame_count;
698
36
    while (left < right) {
699
24
        uint32_t mid = left + (right - left) / 2;
700
24
        T midValue = decode_frame_min_value(mid);
701
24
        if (midValue < target) {
702
12
            left = mid + 1;
703
12
        } else {
704
12
            right = mid;
705
12
        }
706
24
    }
707
    // after loop, left is the first frame >= target
708
12
    if (left == 0) {
709
        // all frames are >= target, not found
710
4
        return _frame_count;
711
4
    }
712
    // otherwise previous frame is the last frame < target
713
8
    return left - 1;
714
12
}
Unexecuted instantiation: _ZN5doris10ForDecoderIaE28seek_last_frame_before_valueEa
Unexecuted instantiation: _ZN5doris10ForDecoderIsE28seek_last_frame_before_valueEs
Unexecuted instantiation: _ZN5doris10ForDecoderIiE28seek_last_frame_before_valueEi
_ZN5doris10ForDecoderIlE28seek_last_frame_before_valueEl
Line
Count
Source
694
12
uint32_t ForDecoder<T>::seek_last_frame_before_value(T target) {
695
    // first of all, find the first frame >= target
696
12
    uint32_t left = 0;
697
12
    uint32_t right = _frame_count;
698
36
    while (left < right) {
699
24
        uint32_t mid = left + (right - left) / 2;
700
24
        T midValue = decode_frame_min_value(mid);
701
24
        if (midValue < target) {
702
12
            left = mid + 1;
703
12
        } else {
704
12
            right = mid;
705
12
        }
706
24
    }
707
    // after loop, left is the first frame >= target
708
12
    if (left == 0) {
709
        // all frames are >= target, not found
710
4
        return _frame_count;
711
4
    }
712
    // otherwise previous frame is the last frame < target
713
8
    return left - 1;
714
12
}
Unexecuted instantiation: _ZN5doris10ForDecoderInE28seek_last_frame_before_valueEn
Unexecuted instantiation: _ZN5doris10ForDecoderIhE28seek_last_frame_before_valueEh
Unexecuted instantiation: _ZN5doris10ForDecoderItE28seek_last_frame_before_valueEt
Unexecuted instantiation: _ZN5doris10ForDecoderIjE28seek_last_frame_before_valueEj
Unexecuted instantiation: _ZN5doris10ForDecoderImE28seek_last_frame_before_valueEm
Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE28seek_last_frame_before_valueES1_
Unexecuted instantiation: _ZN5doris10ForDecoderIoE28seek_last_frame_before_valueEo
715
716
template <typename T>
717
bool ForDecoder<T>::seek_lower_bound_inside_frame(uint32_t frame_index, T target,
718
8
                                                  bool* exact_match) {
719
8
    _current_index = frame_index * _max_frame_size;
720
8
    decode_current_frame(_out_buffer.data());
721
8
    auto end = _out_buffer.begin() + frame_size(frame_index);
722
8
    auto pos = std::lower_bound(_out_buffer.begin(), end, target);
723
8
    if (pos != end) { // found in this frame
724
4
        auto pos_in_frame = cast_set<uint32_t>(std::distance(_out_buffer.begin(), pos));
725
4
        *exact_match = _out_buffer[pos_in_frame] == target;
726
4
        _current_index += pos_in_frame;
727
4
        return true;
728
4
    }
729
4
    return false;
730
8
}
Unexecuted instantiation: _ZN5doris10ForDecoderIaE29seek_lower_bound_inside_frameEjaPb
Unexecuted instantiation: _ZN5doris10ForDecoderIsE29seek_lower_bound_inside_frameEjsPb
Unexecuted instantiation: _ZN5doris10ForDecoderIiE29seek_lower_bound_inside_frameEjiPb
_ZN5doris10ForDecoderIlE29seek_lower_bound_inside_frameEjlPb
Line
Count
Source
718
8
                                                  bool* exact_match) {
719
8
    _current_index = frame_index * _max_frame_size;
720
8
    decode_current_frame(_out_buffer.data());
721
8
    auto end = _out_buffer.begin() + frame_size(frame_index);
722
8
    auto pos = std::lower_bound(_out_buffer.begin(), end, target);
723
8
    if (pos != end) { // found in this frame
724
4
        auto pos_in_frame = cast_set<uint32_t>(std::distance(_out_buffer.begin(), pos));
725
4
        *exact_match = _out_buffer[pos_in_frame] == target;
726
4
        _current_index += pos_in_frame;
727
4
        return true;
728
4
    }
729
4
    return false;
730
8
}
Unexecuted instantiation: _ZN5doris10ForDecoderInE29seek_lower_bound_inside_frameEjnPb
Unexecuted instantiation: _ZN5doris10ForDecoderIhE29seek_lower_bound_inside_frameEjhPb
Unexecuted instantiation: _ZN5doris10ForDecoderItE29seek_lower_bound_inside_frameEjtPb
Unexecuted instantiation: _ZN5doris10ForDecoderIjE29seek_lower_bound_inside_frameEjjPb
Unexecuted instantiation: _ZN5doris10ForDecoderImE29seek_lower_bound_inside_frameEjmPb
Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE29seek_lower_bound_inside_frameEjS1_Pb
Unexecuted instantiation: _ZN5doris10ForDecoderIoE29seek_lower_bound_inside_frameEjoPb
731
732
template <typename T>
733
12
bool ForDecoder<T>::seek_at_or_after_value(const void* value, bool* exact_match) {
734
12
    T target = *reinterpret_cast<const T*>(value);
735
12
    uint32_t frame_to_search = seek_last_frame_before_value(target);
736
12
    if (frame_to_search == _frame_count) {
737
        // all frames are >= target, the searched value must the be first value
738
4
        _current_index = 0;
739
4
        decode_current_frame(_out_buffer.data());
740
4
        *exact_match = _out_buffer[0] == target;
741
4
        return true;
742
4
    }
743
    // binary search inside the last frame < target
744
8
    bool found = seek_lower_bound_inside_frame(frame_to_search, target, exact_match);
745
    // if not found, all values in the last frame are less than target.
746
    // then the searched value must be the first value of the next frame.
747
8
    if (!found && frame_to_search < _frame_count - 1) {
748
2
        _current_index = (frame_to_search + 1) * _max_frame_size;
749
2
        decode_current_frame(_out_buffer.data());
750
2
        *exact_match = _out_buffer[0] == target;
751
2
        return true;
752
2
    }
753
6
    return found;
754
8
}
Unexecuted instantiation: _ZN5doris10ForDecoderIaE22seek_at_or_after_valueEPKvPb
Unexecuted instantiation: _ZN5doris10ForDecoderIsE22seek_at_or_after_valueEPKvPb
Unexecuted instantiation: _ZN5doris10ForDecoderIiE22seek_at_or_after_valueEPKvPb
_ZN5doris10ForDecoderIlE22seek_at_or_after_valueEPKvPb
Line
Count
Source
733
12
bool ForDecoder<T>::seek_at_or_after_value(const void* value, bool* exact_match) {
734
12
    T target = *reinterpret_cast<const T*>(value);
735
12
    uint32_t frame_to_search = seek_last_frame_before_value(target);
736
12
    if (frame_to_search == _frame_count) {
737
        // all frames are >= target, the searched value must the be first value
738
4
        _current_index = 0;
739
4
        decode_current_frame(_out_buffer.data());
740
4
        *exact_match = _out_buffer[0] == target;
741
4
        return true;
742
4
    }
743
    // binary search inside the last frame < target
744
8
    bool found = seek_lower_bound_inside_frame(frame_to_search, target, exact_match);
745
    // if not found, all values in the last frame are less than target.
746
    // then the searched value must be the first value of the next frame.
747
8
    if (!found && frame_to_search < _frame_count - 1) {
748
2
        _current_index = (frame_to_search + 1) * _max_frame_size;
749
2
        decode_current_frame(_out_buffer.data());
750
2
        *exact_match = _out_buffer[0] == target;
751
2
        return true;
752
2
    }
753
6
    return found;
754
8
}
Unexecuted instantiation: _ZN5doris10ForDecoderInE22seek_at_or_after_valueEPKvPb
Unexecuted instantiation: _ZN5doris10ForDecoderIhE22seek_at_or_after_valueEPKvPb
Unexecuted instantiation: _ZN5doris10ForDecoderItE22seek_at_or_after_valueEPKvPb
Unexecuted instantiation: _ZN5doris10ForDecoderIjE22seek_at_or_after_valueEPKvPb
Unexecuted instantiation: _ZN5doris10ForDecoderImE22seek_at_or_after_valueEPKvPb
Unexecuted instantiation: _ZN5doris10ForDecoderINS_8uint24_tEE22seek_at_or_after_valueEPKvPb
Unexecuted instantiation: _ZN5doris10ForDecoderIoE22seek_at_or_after_valueEPKvPb
755
756
template class ForEncoder<int8_t>;
757
template class ForEncoder<int16_t>;
758
template class ForEncoder<int32_t>;
759
template class ForEncoder<int64_t>;
760
template class ForEncoder<int128_t>;
761
template class ForEncoder<uint8_t>;
762
template class ForEncoder<uint16_t>;
763
template class ForEncoder<uint32_t>;
764
template class ForEncoder<uint64_t>;
765
template class ForEncoder<uint24_t>;
766
template class ForEncoder<uint128_t>;
767
768
template class ForDecoder<int8_t>;
769
template class ForDecoder<int16_t>;
770
template class ForDecoder<int32_t>;
771
template class ForDecoder<int64_t>;
772
template class ForDecoder<int128_t>;
773
template class ForDecoder<uint8_t>;
774
template class ForDecoder<uint16_t>;
775
template class ForDecoder<uint32_t>;
776
template class ForDecoder<uint64_t>;
777
template class ForDecoder<uint24_t>;
778
template class ForDecoder<uint128_t>;
779
} // namespace doris