Coverage Report

Created: 2026-07-12 20:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/io/fs/file_meta_cache.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 <cstdint>
21
#include <memory>
22
#include <string>
23
#include <string_view>
24
25
#include "common/status.h"
26
#include "io/file_factory.h"
27
#include "io/fs/file_reader_writer_fwd.h"
28
#include "util/obj_lru_cache.h"
29
30
namespace doris {
31
32
enum class FileMetaCacheFormat : uint8_t {
33
    PARQUET = 1,
34
    ORC = 2,
35
};
36
37
struct FileMetaCacheContext {
38
    FileMetaCacheFormat format;
39
    const std::string& key;
40
    int64_t modification_time = 0;
41
    int64_t file_size = 0;
42
    bool enable_memory_cache = true;
43
};
44
45
enum class FileMetaCacheLookupState {
46
    MEMORY_HIT,
47
    PERSISTED_HIT,
48
    MISS,
49
};
50
51
struct FileMetaCacheLookupResult {
52
    FileMetaCacheLookupState state = FileMetaCacheLookupState::MISS;
53
};
54
55
struct FileMetaCacheInsertResult {
56
    bool memory_inserted = false;
57
    bool persisted_inserted = false;
58
};
59
60
struct FileMetaCacheProfile {
61
    int64_t* hit_cache = nullptr;
62
    int64_t* hit_memory_cache = nullptr;
63
    int64_t* hit_disk_cache = nullptr;
64
    int64_t* miss_disk_cache = nullptr;
65
    int64_t* write_disk_cache = nullptr;
66
    int64_t* read_disk_cache_time = nullptr;
67
    int64_t* write_disk_cache_time = nullptr;
68
};
69
70
class FileMetaPersistentCache {
71
public:
72
    virtual ~FileMetaPersistentCache() = default;
73
74
    virtual Status read(FileMetaCacheFormat format, const std::string& key,
75
                        int64_t modification_time, int64_t file_size, std::string* payload) = 0;
76
77
    virtual Status write(FileMetaCacheFormat format, const std::string& key,
78
                         int64_t modification_time, int64_t file_size,
79
                         std::string_view payload) = 0;
80
81
    virtual void remove(FileMetaCacheFormat format, const std::string& key) = 0;
82
};
83
84
// A file meta cache depends on a LRU cache.
85
// Such as parsed parquet footer.
86
// The capacity will limit the number of cache entries in cache.
87
class FileMetaCache {
88
public:
89
    explicit FileMetaCache(int64_t capacity,
90
                           std::unique_ptr<FileMetaPersistentCache> persistent_cache = nullptr);
91
92
    FileMetaCache(const FileMetaCache&) = delete;
93
    const FileMetaCache& operator=(const FileMetaCache&) = delete;
94
95
0
    ObjLRUCache& cache() { return _cache; }
96
97
    static std::string get_key(const std::string file_name, int64_t modification_time,
98
                               int64_t file_size);
99
100
    static std::string get_key(io::FileReaderSPtr file_reader,
101
                               const io::FileDescription& _file_description);
102
103
    static bool is_persistent_cache_enabled();
104
    static bool is_persistent_cache_payload_size_allowed(uint64_t payload_size);
105
106
3.95k
    bool lookup(const std::string& key, ObjLRUCache::CacheHandle* handle) {
107
3.95k
        return _cache.lookup({key}, handle);
108
3.95k
    }
109
110
    template <typename T>
111
553
    void insert(const std::string& key, T* value, ObjLRUCache::CacheHandle* handle) {
112
553
        _cache.insert({key}, value, handle);
113
553
    }
_ZN5doris13FileMetaCache6insertINS_12FileMetaDataEEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPT_PNS_11ObjLRUCache11CacheHandleE
Line
Count
Source
111
238
    void insert(const std::string& key, T* value, ObjLRUCache::CacheHandle* handle) {
112
238
        _cache.insert({key}, value, handle);
113
238
    }
_ZN5doris13FileMetaCache6insertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_PT_PNS_11ObjLRUCache11CacheHandleE
Line
Count
Source
111
315
    void insert(const std::string& key, T* value, ObjLRUCache::CacheHandle* handle) {
112
315
        _cache.insert({key}, value, handle);
113
315
    }
114
115
    template <typename T>
116
    bool insert(const std::string& key, std::unique_ptr<T>& value,
117
                ObjLRUCache::CacheHandle* handle) {
118
        DCHECK(value != nullptr);
119
        if (!_cache.enabled()) {
120
            return false;
121
        }
122
        _cache.insert({key}, value.release(), handle);
123
        return true;
124
    }
125
126
8.00k
    bool enabled() const { return _cache.enabled(); }
127
128
    FileMetaCacheLookupResult lookup(const FileMetaCacheContext& context,
129
                                     ObjLRUCache::CacheHandle* handle, std::string* serialized_meta,
130
                                     FileMetaCacheProfile* profile = nullptr);
131
132
    void invalidate_persistent_cache(const FileMetaCacheContext& context);
133
134
    template <typename T>
135
    FileMetaCacheInsertResult insert(const FileMetaCacheContext& context, std::unique_ptr<T>& value,
136
                                     ObjLRUCache::CacheHandle* handle,
137
                                     std::string_view serialized_meta,
138
                                     FileMetaCacheProfile* profile = nullptr) {
139
        FileMetaCacheInsertResult result;
140
        int64_t persisted_write_time = 0;
141
        result.persisted_inserted =
142
                insert_persistent_cache(context, serialized_meta, &persisted_write_time);
143
        if (result.persisted_inserted && profile != nullptr) {
144
            if (profile->write_disk_cache != nullptr) {
145
                ++(*profile->write_disk_cache);
146
            }
147
            if (profile->write_disk_cache_time != nullptr) {
148
                *profile->write_disk_cache_time += persisted_write_time;
149
            }
150
        }
151
        if (context.enable_memory_cache) {
152
            result.memory_inserted = insert(context.key, value, handle);
153
        }
154
        return result;
155
    }
156
157
private:
158
    bool lookup_persistent_cache(const FileMetaCacheContext& context, std::string* payload,
159
                                 int64_t* read_time);
160
    bool insert_persistent_cache(const FileMetaCacheContext& context, std::string_view payload,
161
                                 int64_t* write_time);
162
163
    ObjLRUCache _cache;
164
    std::unique_ptr<FileMetaPersistentCache> _persistent_cache;
165
};
166
167
} // namespace doris