Coverage Report

Created: 2026-10-21 21:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/storage/index/index_writer.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 <atomic>
25
#include <memory>
26
#include <string>
27
#include <vector>
28
29
#include "common/config.h"
30
#include "common/status.h"
31
#include "io/fs/file_system.h"
32
#include "io/fs/local_file_system.h"
33
#include "storage/olap_common.h"
34
#include "storage/options.h"
35
36
namespace doris {
37
38
class TabletIndex;
39
class TabletColumn;
40
41
namespace segment_v2 {
42
class IndexFileWriter;
43
44
class IndexColumnWriter {
45
public:
46
    static Status create(const TabletColumn* column, std::unique_ptr<IndexColumnWriter>* res,
47
                         IndexFileWriter* index_file_writer, const TabletIndex* inverted_index);
48
    virtual Status init() = 0;
49
50
2.80k
    IndexColumnWriter() = default;
51
2.80k
    virtual ~IndexColumnWriter() = default;
52
53
    // Aligned storage values: fixed-width cells or Slice descriptors. The writer's
54
    // field type determines the layout; count is the number of values.
55
    virtual Status add_values(const std::string name, const uint8_t* values, size_t count) = 0;
56
57
    // One document per array row. null_map describes items, and adjacent offsets
58
    // give each row's item count. Values use the same storage layout as add_values.
59
    virtual Status add_array_values(size_t field_size, const uint8_t* value_ptr,
60
                                    const uint8_t* null_map, const uint64_t* offsets_ptr,
61
                                    size_t count) = 0;
62
63
    virtual Status add_nulls(uint32_t count) = 0;
64
    virtual Status add_array_nulls(const uint8_t* null_map, size_t num_rows) = 0;
65
66
    // Write-path hint from the segment writer: this writer serves a direct load
67
    // (stream/broker load, DataWriteType::TYPE_DIRECT) as opposed to compaction
68
    // / schema change / index build. The column writer forwards it
69
    // unconditionally right after create() succeeds (i.e. after init(), before
70
    // any value is added); creation paths outside the column writer (e.g. ADD
71
    // INDEX in index_builder.cpp) never call it and keep the non-direct default.
72
    // Default no-op: SNII uses it to select the direct-load PRX zstd level.
73
2.34k
    virtual void set_direct_load(bool /*is_direct_load*/) {}
74
75
    virtual Status finish() = 0;
76
77
    virtual int64_t size() const = 0;
78
79
    virtual void close_on_error() = 0;
80
81
    // check if the column is valid for inverted index, some columns
82
    // are generated from variant, but not all of them are supported
83
    static bool check_support_inverted_index(const TabletColumn& column);
84
85
    static bool check_support_ann_index(const TabletColumn& column);
86
};
87
88
class TmpFileDirs {
89
public:
90
501
    TmpFileDirs(const std::vector<doris::StorePath>& store_paths) {
91
558
        for (const auto& store_path : store_paths) {
92
558
            _tmp_file_dirs.emplace_back(store_path.path + "/" + config::tmp_file_dir);
93
558
        }
94
501
    };
95
96
501
    Status init() {
97
558
        for (auto& tmp_file_dir : _tmp_file_dirs) {
98
            // delete the tmp dir to avoid the tmp files left by last crash
99
558
            RETURN_IF_ERROR(io::global_local_filesystem()->delete_directory(tmp_file_dir));
100
558
            RETURN_IF_ERROR(io::global_local_filesystem()->create_directory(tmp_file_dir));
101
558
        }
102
501
        return Status::OK();
103
501
    };
104
105
35.0k
    io::Path get_tmp_file_dir() {
106
35.0k
        size_t cur_index = _next_index.fetch_add(1);
107
35.0k
        return _tmp_file_dirs[cur_index % _tmp_file_dirs.size()];
108
35.0k
    };
109
110
private:
111
    std::vector<io::Path> _tmp_file_dirs;
112
    std::atomic_size_t _next_index {0}; // use for round-robin
113
};
114
115
} // namespace segment_v2
116
117
} // namespace doris