Coverage Report

Created: 2026-10-12 09:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/io/fs/file_system.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 <glog/logging.h>
22
23
#include <cstdint>
24
#include <functional>
25
#include <memory>
26
#include <optional>
27
#include <string>
28
#include <vector>
29
30
#include "common/status.h"
31
#include "io/fs/file_reader_writer_fwd.h"
32
#include "io/fs/path.h"
33
34
namespace doris::io {
35
36
#ifndef FILESYSTEM_M
37
#define FILESYSTEM_M(stmt)                                  \
38
4.65M
    do {                                                    \
39
4.65M
        Status _s;                                          \
40
4.67M
        if (bthread_self() == 0) {                          \
41
4.67M
            _s = (stmt);                                    \
42
18.4E
        } else {                                            \
43
18.4E
            auto task = [&] { _s = (stmt); };               \
Unexecuted instantiation: unity_2_cxx.cxx:_ZZN5doris2io15LocalFileSystem24delete_directory_or_fileERKNSt10filesystem7__cxx114pathEENK3$_0clEv
Unexecuted instantiation: unity_2_cxx.cxx:_ZZN5doris2io15LocalFileSystem22delete_empty_directoryERKNSt10filesystem7__cxx114pathEENK3$_0clEv
Unexecuted instantiation: unity_2_cxx.cxx:_ZZN5doris2io15LocalFileSystem9link_fileERKNSt10filesystem7__cxx114pathES6_ENK3$_0clEv
Unexecuted instantiation: unity_2_cxx.cxx:_ZZN5doris2io15LocalFileSystem6md5sumERKNSt10filesystem7__cxx114pathEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEENK3$_0clEv
Unexecuted instantiation: unity_2_cxx.cxx:_ZZN5doris2io15LocalFileSystem17iterate_directoryERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt8functionIFbRKNS0_8FileInfoEEEENK3$_0clEv
Unexecuted instantiation: unity_2_cxx.cxx:_ZZN5doris2io15LocalFileSystem14get_space_infoERKNSt10filesystem7__cxx114pathEPmS7_ENK3$_0clEv
Unexecuted instantiation: unity_2_cxx.cxx:_ZZN5doris2io15LocalFileSystem14get_inode_infoERKNSt10filesystem7__cxx114pathEPmS7_ENK3$_0clEv
Unexecuted instantiation: unity_2_cxx.cxx:_ZZN5doris2io15LocalFileSystem9copy_pathERKNSt10filesystem7__cxx114pathES6_ENK3$_0clEv
Unexecuted instantiation: unity_2_cxx.cxx:_ZZN5doris2io15LocalFileSystem10permissionERKNSt10filesystem7__cxx114pathENS2_5permsEENK3$_0clEv
Unexecuted instantiation: unity_2_cxx.cxx:_ZZN5doris2io16RemoteFileSystem6uploadERKNSt10filesystem7__cxx114pathES6_ENK3$_0clEv
Unexecuted instantiation: unity_2_cxx.cxx:_ZZN5doris2io16RemoteFileSystem12batch_uploadERKSt6vectorINSt10filesystem7__cxx114pathESaIS5_EES9_ENK3$_0clEv
Unexecuted instantiation: unity_2_cxx.cxx:_ZZN5doris2io16RemoteFileSystem8downloadERKNSt10filesystem7__cxx114pathES6_ENK3$_0clEv
Unexecuted instantiation: unity_1_cxx.cxx:_ZZN5doris2io10FileSystem11create_fileERKNSt10filesystem7__cxx114pathEPSt10unique_ptrINS0_10FileWriterESt14default_deleteIS8_EEPKNS0_17FileWriterOptionsEENK3$_0clEv
Unexecuted instantiation: unity_1_cxx.cxx:_ZZN5doris2io10FileSystem9open_fileERKNSt10filesystem7__cxx114pathEPSt10shared_ptrINS0_10FileReaderEEPKNS0_17FileReaderOptionsEENK3$_0clEv
Unexecuted instantiation: unity_1_cxx.cxx:_ZZN5doris2io10FileSystem16create_directoryERKNSt10filesystem7__cxx114pathEbENK3$_0clEv
unity_1_cxx.cxx:_ZZN5doris2io10FileSystem11delete_fileERKNSt10filesystem7__cxx114pathEENK3$_0clEv
Line
Count
Source
43
3
            auto task = [&] { _s = (stmt); };               \
Unexecuted instantiation: unity_1_cxx.cxx:_ZZN5doris2io10FileSystem16delete_directoryERKNSt10filesystem7__cxx114pathEENK3$_0clEv
Unexecuted instantiation: unity_1_cxx.cxx:_ZZN5doris2io10FileSystem12batch_deleteERKSt6vectorINSt10filesystem7__cxx114pathESaIS5_EEENK3$_0clEv
Unexecuted instantiation: unity_1_cxx.cxx:_ZZNK5doris2io10FileSystem6existsERKNSt10filesystem7__cxx114pathEPbENK3$_0clEv
Unexecuted instantiation: unity_1_cxx.cxx:_ZZNK5doris2io10FileSystem9file_sizeERKNSt10filesystem7__cxx114pathEPlENK3$_0clEv
Unexecuted instantiation: unity_1_cxx.cxx:_ZZNK5doris2io10FileSystem4statERKNSt10filesystem7__cxx114pathEPNS0_8FileStatEPNS0_15FileStatContextEENK3$_0clEv
Unexecuted instantiation: unity_1_cxx.cxx:_ZZN5doris2io10FileSystem4listERKNSt10filesystem7__cxx114pathEbPSt6vectorINS0_8FileInfoESaIS8_EEPbENK3$_0clEv
Unexecuted instantiation: unity_1_cxx.cxx:_ZZN5doris2io10FileSystem6renameERKNSt10filesystem7__cxx114pathES6_ENK3$_0clEv
44
18.4E
            AsyncIO::run_task(task, _type);                 \
45
18.4E
        }                                                   \
46
4.65M
        if (!_s) {                                          \
47
68.4k
            _s = Status::Error<false>(_s.code(), _s.msg()); \
48
68.4k
        }                                                   \
49
4.65M
        return _s;                                          \
50
4.65M
    } while (0);
51
#endif
52
53
enum class FileSystemType : uint8_t { LOCAL, S3, HDFS, BROKER, HTTP };
54
55
0
inline std::ostream& operator<<(std::ostream& ostr, FileSystemType type) {
56
0
    switch (type) {
57
0
    case FileSystemType::LOCAL:
58
0
        ostr << "LOCAL";
59
0
        return ostr;
60
0
    case FileSystemType::S3:
61
0
        ostr << "S3";
62
0
        return ostr;
63
0
    case FileSystemType::HDFS:
64
0
        ostr << "HDFS";
65
0
        return ostr;
66
0
    case FileSystemType::BROKER:
67
0
        ostr << "BROKER";
68
0
        return ostr;
69
0
    case FileSystemType::HTTP:
70
0
        ostr << "HTTP";
71
0
        return ostr;
72
0
    default:
73
0
        ostr << "UNKNOWN";
74
0
        return ostr;
75
0
    }
76
0
}
77
78
struct FileInfo {
79
    // only file name, no path
80
    std::string file_name;
81
    int64_t file_size;
82
    bool is_file;
83
};
84
85
struct FileStat {
86
    int64_t size = 0;
87
    std::optional<std::string> content_type {};
88
    // Provider ETag as an opaque ETAG:digest, when available.
89
    std::optional<std::string> checksum {};
90
};
91
92
// Query-owned cancellation, checked before and after the stock metadata operation.
93
struct FileStatContext {
94
    std::function<bool()> is_cancelled {};
95
};
96
97
// `FileSystem` providing an interface to access FS metadata. Each `RemoteFileSystem` instance
98
// (except temporary Remote FS) corresponds to a `StorageResource` configured in FE.
99
class FileSystem {
100
public:
101
    // Sometimes `FileSystem` instance maybe a temporary instance which has no corresponding
102
    // Resource, then use `TMP_FS_ID` as FS id.
103
    inline static const std::string TMP_FS_ID;
104
105
    // The following are public interface.
106
    // And derived classes should implement all xxx_impl methods.
107
    Status create_file(const Path& file, FileWriterPtr* writer,
108
                       const FileWriterOptions* opts = nullptr);
109
    Status open_file(const Path& file, FileReaderSPtr* reader,
110
                     const FileReaderOptions* opts = nullptr);
111
    Status create_directory(const Path& dir, bool failed_if_exists = false);
112
    Status delete_file(const Path& file);
113
    Status delete_directory(const Path& dir);
114
    Status batch_delete(const std::vector<Path>& files);
115
    Status exists(const Path& path, bool* res) const;
116
    Status file_size(const Path& file, int64_t* file_size) const;
117
    // On error, metadata is unchanged.
118
    Status stat(const Path& path, FileStat* metadata, FileStatContext* context = nullptr) const;
119
    Status list(const Path& dir, bool only_file, std::vector<FileInfo>* files, bool* exists);
120
    Status rename(const Path& orig_name, const Path& new_name);
121
122
281k
    const std::string& id() const { return _id; }
123
    // file system type
124
194k
    FileSystemType type() const { return _type; }
125
126
2.22k
    virtual ~FileSystem() = default;
127
128
    // Each derived class should implement create method to create fs.
129
    FileSystem(const FileSystem&) = delete;
130
    const FileSystem& operator=(const FileSystem&) = delete;
131
132
protected:
133
    /// create file and return a FileWriter
134
    virtual Status create_file_impl(const Path& file, FileWriterPtr* writer,
135
                                    const FileWriterOptions* opts) = 0;
136
137
    /// open file and return a FileReader
138
    virtual Status open_file_impl(const Path& file, FileReaderSPtr* reader,
139
                                  const FileReaderOptions* opts) = 0;
140
141
    /// create directory recursively
142
    virtual Status create_directory_impl(const Path& dir, bool failed_if_exists = false) = 0;
143
144
    /// delete file.
145
    /// return OK if file does not exist
146
    /// return ERR if not a regular file
147
    virtual Status delete_file_impl(const Path& file) = 0;
148
149
    /// delete all files in "files"
150
    virtual Status batch_delete_impl(const std::vector<Path>& files) = 0;
151
152
    /// remove all under directory recursively
153
    /// return OK if dir does not exist
154
    /// return ERR if not a dir
155
    virtual Status delete_directory_impl(const Path& dir) = 0;
156
157
    /// check if path exist
158
    /// return OK and res = 1 means exist, res = 0 means does not exist
159
    /// return ERR otherwise
160
    virtual Status exists_impl(const Path& path, bool* res) const = 0;
161
162
    /// return OK and get size of given file, save in "file_size".
163
    /// return ERR otherwise
164
    virtual Status file_size_impl(const Path& file, int64_t* file_size) const = 0;
165
166
    virtual Status stat_impl(const Path& path, FileStat* metadata, FileStatContext* context) const;
167
168
    /// return OK and list all objects in "dir", save in "files"
169
    /// return ERR otherwise
170
    /// will not traverse dir recursively.
171
    /// if "only_file" is true, will only return regular files, otherwise, return files and subdirs.
172
    /// the existence of dir will be saved in "exists"
173
    /// if "dir" does not exist, it will return Status::OK, but "exists" will to false
174
    virtual Status list_impl(const Path& dir, bool only_file, std::vector<FileInfo>* files,
175
                             bool* exists) = 0;
176
177
    /// rename file from orig_name to new_name
178
    virtual Status rename_impl(const Path& orig_name, const Path& new_name) = 0;
179
180
    // FIMXE(plat1ko): The implementation and semantics of this function are not completely
181
    // consistent, which is confused.
182
    virtual Status absolute_path(const Path& path, Path& abs_path) const = 0;
183
184
2.25k
    FileSystem(std::string id, FileSystemType type) : _id(std::move(id)), _type(type) {}
185
186
    // FS uid, corresponds to the `StorageResource` id generated by FE or MetaService.
187
    // Although resource id in FE is int64 now, we use string type for flexible extensibility.
188
    std::string _id;
189
    FileSystemType _type;
190
};
191
192
using FileSystemSPtr = std::shared_ptr<FileSystem>;
193
194
} // namespace doris::io