Coverage Report

Created: 2026-03-12 17:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/storage/row_cursor.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#pragma once
19
20
#include <butil/macros.h>
21
#include <stddef.h>
22
#include <stdint.h>
23
24
#include <memory>
25
#include <string>
26
#include <vector>
27
28
#include "common/consts.h"
29
#include "common/status.h"
30
#include "storage/olap_tuple.h"
31
#include "storage/row_cursor_cell.h"
32
#include "storage/schema.h"
33
#include "storage/tablet/tablet_schema.h"
34
35
namespace doris {
36
#include "common/compile_check_begin.h"
37
class StorageField;
38
39
// Delegate the operation of a row of data
40
class RowCursor {
41
public:
42
    static const int DEFAULT_TEXT_LENGTH = 128;
43
44
    RowCursor();
45
46
    // Traverse and destroy the field cursor
47
    ~RowCursor();
48
49
    // Initialize with the size of the key, currently only used when splitting the range of key
50
    Status init_scan_key(TabletSchemaSPtr schema, const std::vector<std::string>& keys);
51
52
    Status init_scan_key(TabletSchemaSPtr schema, const std::vector<std::string>& keys,
53
                         const std::shared_ptr<Schema>& shared_schema);
54
55
7.61M
    RowCursorCell cell(uint32_t cid) const { return RowCursorCell(_nullable_cell_ptr(cid)); }
56
57
    // Deserialize the value of each field from the string array,
58
    // Each array item must be a \0 terminated string
59
    // and the input string and line cursor need the same number of columns
60
    Status from_tuple(const OlapTuple& tuple);
61
62
    // Output row cursor content in string format
63
    std::string to_string() const;
64
65
    // this two functions is used in unit test
66
    size_t get_fixed_len() const { return _fixed_len; }
67
    size_t get_variable_len() const { return _variable_len; }
68
69
6.67M
    const StorageField* column_schema(uint32_t cid) const { return _schema->column(cid); }
70
71
2.90M
    const Schema* schema() const { return _schema.get(); }
72
73
    // Encode one row into binary according given num_keys.
74
    // A cell will be encoded in the format of a marker and encoded content.
75
    // When encoding row, if any cell isn't found in row, this function will
76
    // fill a marker and return. If padding_minimal is true, KEY_MINIMAL_MARKER will
77
    // be added, if padding_minimal is false, KEY_MAXIMAL_MARKER will be added.
78
    // If all num_keys are found in row, no marker will be added.
79
    template <bool is_mow = false>
80
925k
    void encode_key_with_padding(std::string* buf, size_t num_keys, bool padding_minimal) const {
81
4.53M
        for (uint32_t cid = 0; cid < num_keys; cid++) {
82
4.53M
            auto field = _schema->column(cid);
83
4.53M
            if (field == nullptr) {
84
918k
                if (padding_minimal) {
85
419k
                    buf->push_back(KeyConsts::KEY_MINIMAL_MARKER);
86
498k
                } else {
87
498k
                    if (is_mow) {
88
488k
                        buf->push_back(KeyConsts::KEY_NORMAL_NEXT_MARKER);
89
488k
                    } else {
90
10.1k
                        buf->push_back(KeyConsts::KEY_MAXIMAL_MARKER);
91
10.1k
                    }
92
498k
                }
93
918k
                break;
94
918k
            }
95
96
3.61M
            auto c = cell(cid);
97
3.61M
            if (c.is_null()) {
98
2.74k
                buf->push_back(KeyConsts::KEY_NULL_FIRST_MARKER);
99
2.74k
                continue;
100
2.74k
            }
101
3.60M
            buf->push_back(KeyConsts::KEY_NORMAL_MARKER);
102
3.60M
            if (is_mow) {
103
3.59M
                field->full_encode_ascending(c.cell_ptr(), buf);
104
3.59M
            } else {
105
18.2k
                field->encode_ascending(c.cell_ptr(), buf);
106
18.2k
            }
107
3.60M
        }
108
925k
    }
_ZNK5doris9RowCursor23encode_key_with_paddingILb0EEEvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEmb
Line
Count
Source
80
21.8k
    void encode_key_with_padding(std::string* buf, size_t num_keys, bool padding_minimal) const {
81
43.7k
        for (uint32_t cid = 0; cid < num_keys; cid++) {
82
40.1k
            auto field = _schema->column(cid);
83
40.1k
            if (field == nullptr) {
84
18.2k
                if (padding_minimal) {
85
7.90k
                    buf->push_back(KeyConsts::KEY_MINIMAL_MARKER);
86
10.3k
                } else {
87
10.3k
                    if (is_mow) {
88
0
                        buf->push_back(KeyConsts::KEY_NORMAL_NEXT_MARKER);
89
10.3k
                    } else {
90
10.3k
                        buf->push_back(KeyConsts::KEY_MAXIMAL_MARKER);
91
10.3k
                    }
92
10.3k
                }
93
18.2k
                break;
94
18.2k
            }
95
96
21.8k
            auto c = cell(cid);
97
21.8k
            if (c.is_null()) {
98
2.58k
                buf->push_back(KeyConsts::KEY_NULL_FIRST_MARKER);
99
2.58k
                continue;
100
2.58k
            }
101
19.2k
            buf->push_back(KeyConsts::KEY_NORMAL_MARKER);
102
19.2k
            if (is_mow) {
103
0
                field->full_encode_ascending(c.cell_ptr(), buf);
104
19.2k
            } else {
105
19.2k
                field->encode_ascending(c.cell_ptr(), buf);
106
19.2k
            }
107
19.2k
        }
108
21.8k
    }
_ZNK5doris9RowCursor23encode_key_with_paddingILb1EEEvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEmb
Line
Count
Source
80
903k
    void encode_key_with_padding(std::string* buf, size_t num_keys, bool padding_minimal) const {
81
4.49M
        for (uint32_t cid = 0; cid < num_keys; cid++) {
82
4.49M
            auto field = _schema->column(cid);
83
4.49M
            if (field == nullptr) {
84
900k
                if (padding_minimal) {
85
411k
                    buf->push_back(KeyConsts::KEY_MINIMAL_MARKER);
86
488k
                } else {
87
488k
                    if (is_mow) {
88
488k
                        buf->push_back(KeyConsts::KEY_NORMAL_NEXT_MARKER);
89
18.4E
                    } else {
90
18.4E
                        buf->push_back(KeyConsts::KEY_MAXIMAL_MARKER);
91
18.4E
                    }
92
488k
                }
93
900k
                break;
94
900k
            }
95
96
3.59M
            auto c = cell(cid);
97
3.59M
            if (c.is_null()) {
98
168
                buf->push_back(KeyConsts::KEY_NULL_FIRST_MARKER);
99
168
                continue;
100
168
            }
101
3.59M
            buf->push_back(KeyConsts::KEY_NORMAL_MARKER);
102
3.59M
            if (is_mow) {
103
3.59M
                field->full_encode_ascending(c.cell_ptr(), buf);
104
18.4E
            } else {
105
18.4E
                field->encode_ascending(c.cell_ptr(), buf);
106
18.4E
            }
107
3.59M
        }
108
903k
    }
109
110
    // Encode one row into binary according given num_keys.
111
    // Client call this function must assure that row contains the first
112
    // num_keys columns.
113
    template <bool full_encode = false>
114
129k
    void encode_key(std::string* buf, size_t num_keys) const {
115
387k
        for (uint32_t cid = 0; cid < num_keys; cid++) {
116
258k
            auto c = cell(cid);
117
258k
            if (c.is_null()) {
118
1
                buf->push_back(KeyConsts::KEY_NULL_FIRST_MARKER);
119
1
                continue;
120
1
            }
121
258k
            buf->push_back(KeyConsts::KEY_NORMAL_MARKER);
122
258k
            if (full_encode) {
123
258k
                _schema->column(cid)->full_encode_ascending(c.cell_ptr(), buf);
124
258k
            } else {
125
1
                _schema->column(cid)->encode_ascending(c.cell_ptr(), buf);
126
1
            }
127
258k
        }
128
129k
    }
_ZNK5doris9RowCursor10encode_keyILb1EEEvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm
Line
Count
Source
114
129k
    void encode_key(std::string* buf, size_t num_keys) const {
115
387k
        for (uint32_t cid = 0; cid < num_keys; cid++) {
116
258k
            auto c = cell(cid);
117
258k
            if (c.is_null()) {
118
0
                buf->push_back(KeyConsts::KEY_NULL_FIRST_MARKER);
119
0
                continue;
120
0
            }
121
258k
            buf->push_back(KeyConsts::KEY_NORMAL_MARKER);
122
258k
            if (full_encode) {
123
258k
                _schema->column(cid)->full_encode_ascending(c.cell_ptr(), buf);
124
258k
            } else {
125
0
                _schema->column(cid)->encode_ascending(c.cell_ptr(), buf);
126
0
            }
127
258k
        }
128
129k
    }
_ZNK5doris9RowCursor10encode_keyILb0EEEvPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm
Line
Count
Source
114
5
    void encode_key(std::string* buf, size_t num_keys) const {
115
7
        for (uint32_t cid = 0; cid < num_keys; cid++) {
116
2
            auto c = cell(cid);
117
2
            if (c.is_null()) {
118
1
                buf->push_back(KeyConsts::KEY_NULL_FIRST_MARKER);
119
1
                continue;
120
1
            }
121
1
            buf->push_back(KeyConsts::KEY_NORMAL_MARKER);
122
1
            if (full_encode) {
123
0
                _schema->column(cid)->full_encode_ascending(c.cell_ptr(), buf);
124
1
            } else {
125
1
                _schema->column(cid)->encode_ascending(c.cell_ptr(), buf);
126
1
            }
127
1
        }
128
5
    }
129
130
private:
131
    Status _init(TabletSchemaSPtr schema, uint32_t column_count);
132
    Status _init(const std::vector<uint32_t>& columns);
133
    Status _init(const std::shared_ptr<Schema>& shared_schema,
134
                 const std::vector<uint32_t>& columns);
135
    // common init function
136
    Status _init(const std::vector<TabletColumnPtr>& schema, const std::vector<uint32_t>& columns);
137
    Status _alloc_buf();
138
139
    Status _init_scan_key(TabletSchemaSPtr schema, const std::vector<std::string>& scan_keys);
140
141
    // Get column nullable pointer with column id
142
    // TODO(zc): make this return const char*
143
18.2M
    char* _nullable_cell_ptr(uint32_t cid) const {
144
18.2M
        return _fixed_buf + _schema->column_offset(cid);
145
18.2M
    }
146
2.35M
    char* _cell_ptr(uint32_t cid) const { return _fixed_buf + _schema->column_offset(cid) + 1; }
147
148
2.78k
    void _set_null(uint32_t index) const {
149
2.78k
        *reinterpret_cast<bool*>(_nullable_cell_ptr(index)) = true;
150
2.78k
    }
151
152
2.34M
    void _set_not_null(uint32_t index) const {
153
2.34M
        *reinterpret_cast<bool*>(_nullable_cell_ptr(index)) = false;
154
2.34M
    }
155
156
8.28M
    bool _is_null(uint32_t index) const {
157
8.28M
        return *reinterpret_cast<bool*>(_nullable_cell_ptr(index));
158
8.28M
    }
159
160
    std::unique_ptr<Schema> _schema;
161
162
    char* _fixed_buf = nullptr; // point to fixed buf
163
    size_t _fixed_len;
164
    char* _owned_fixed_buf = nullptr; // point to buf allocated in init function
165
166
    char* _variable_buf = nullptr;
167
    size_t _variable_len;
168
    size_t _string_field_count;
169
    char** _long_text_buf = nullptr;
170
171
    std::vector<std::string> _row_string;
172
173
    DISALLOW_COPY_AND_ASSIGN(RowCursor);
174
};
175
#include "common/compile_check_end.h"
176
} // namespace doris