Coverage Report

Created: 2026-03-12 17:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/cloud/delete_bitmap_file_reader.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 "cloud/delete_bitmap_file_reader.h"
19
20
#include "cloud/delete_bitmap_file_writer.h"
21
#include "common/status.h"
22
#include "io/fs/file_reader.h"
23
#include "io/fs/packed_file_reader.h"
24
#include "util/coding.h"
25
26
namespace doris {
27
#include "common/compile_check_begin.h"
28
29
DeleteBitmapFileReader::DeleteBitmapFileReader(int64_t tablet_id, const std::string& rowset_id,
30
                                               std::optional<StorageResource>& storage_resource)
31
1
        : _tablet_id(tablet_id), _rowset_id(rowset_id), _storage_resource(storage_resource) {}
32
33
DeleteBitmapFileReader::DeleteBitmapFileReader(int64_t tablet_id, const std::string& rowset_id,
34
                                               std::optional<StorageResource>& storage_resource,
35
                                               const PackedSliceLocationPB& packed_location)
36
0
        : _tablet_id(tablet_id),
37
0
          _rowset_id(rowset_id),
38
0
          _storage_resource(storage_resource),
39
0
          _is_packed(true),
40
0
          _packed_offset(packed_location.offset()),
41
0
          _packed_size(packed_location.size()),
42
0
          _packed_file_path(packed_location.packed_file_path()),
43
0
          _packed_file_size(packed_location.has_packed_file_size()
44
0
                                    ? packed_location.packed_file_size()
45
0
                                    : -1) {}
46
47
1
DeleteBitmapFileReader::~DeleteBitmapFileReader() = default;
48
49
0
Status DeleteBitmapFileReader::init() {
50
#ifdef BE_TEST
51
    _path = "./log/" + _rowset_id + "_delete_bitmap.db";
52
    bool exists = false;
53
    RETURN_IF_ERROR(io::global_local_filesystem()->exists(_path, &exists));
54
    if (!exists) {
55
        return Status::NotFound("{} doesn't exist", _path);
56
    }
57
    RETURN_IF_ERROR(io::global_local_filesystem()->open_file(_path, &_file_reader));
58
    return Status::OK();
59
#endif
60
0
    if (!_storage_resource) {
61
0
        return Status::InternalError("invalid storage resource for tablet_id={}", _tablet_id);
62
0
    }
63
64
0
    if (_is_packed) {
65
        // Read from packed file
66
0
        io::FileReaderSPtr inner_reader;
67
0
        io::FileReaderOptions opts;
68
0
        if (_packed_file_size > 0) {
69
0
            opts.file_size = _packed_file_size;
70
0
        }
71
0
        opts.cache_type = io::FileCachePolicy::NO_CACHE;
72
0
        RETURN_IF_ERROR(_storage_resource->fs->open_file(io::Path(_packed_file_path), &inner_reader,
73
0
                                                         &opts));
74
75
0
        _path = _storage_resource->remote_delete_bitmap_path(_tablet_id, _rowset_id);
76
0
        _file_reader = std::make_shared<io::PackedFileReader>(
77
0
                std::move(inner_reader), io::Path(_path), _packed_offset, _packed_size);
78
0
    } else {
79
        // Read from standalone file
80
0
        _path = _storage_resource->remote_delete_bitmap_path(_tablet_id, _rowset_id);
81
0
        io::FileReaderOptions opts;
82
0
        RETURN_IF_ERROR(_storage_resource->fs->open_file(_path, &_file_reader, &opts));
83
0
    }
84
0
    return Status::OK();
85
0
}
86
87
1
Status DeleteBitmapFileReader::close() {
88
1
    if (_file_reader) {
89
1
        return _file_reader->close();
90
1
    }
91
0
    return Status::OK();
92
1
}
93
94
1
Status DeleteBitmapFileReader::read(DeleteBitmapPB& delete_bitmap) {
95
1
    size_t bytes_read = 0;
96
1
    size_t offset = 0;
97
    // 0. read magic number
98
1
    {
99
1
        uint8_t magic_buf[DeleteBitmapFileWriter::MAGIC_SIZE];
100
1
        RETURN_IF_ERROR(_file_reader->read_at(
101
1
                offset, {magic_buf, DeleteBitmapFileWriter::MAGIC_SIZE}, &bytes_read));
102
1
        offset += DeleteBitmapFileWriter::MAGIC_SIZE;
103
1
        if (bytes_read != DeleteBitmapFileWriter::MAGIC_SIZE ||
104
1
            memcmp(magic_buf, DeleteBitmapFileWriter::DELETE_BITMAP_MAGIC,
105
1
                   DeleteBitmapFileWriter::MAGIC_SIZE) != 0) {
106
0
            return Status::InternalError(
107
0
                    "read delete bitmap failed from {} because magic is not "
108
0
                    "matched",
109
0
                    _path);
110
0
        }
111
1
    }
112
    // 1. read delete bitmap proto length
113
1
    size_t delete_bitmap_len = 0;
114
1
    {
115
1
        uint8_t len_buf[DeleteBitmapFileWriter::LENGTH_SIZE];
116
1
        RETURN_IF_ERROR(_file_reader->read_at(
117
1
                offset, {len_buf, DeleteBitmapFileWriter::LENGTH_SIZE}, &bytes_read));
118
1
        offset += DeleteBitmapFileWriter::LENGTH_SIZE;
119
1
        delete_bitmap_len = decode_fixed64_le(len_buf);
120
1
        if (delete_bitmap_len == 0) {
121
0
            return Status::InternalError("read delete bitmap failed from {} because length is 0",
122
0
                                         _path);
123
0
        }
124
1
        if (offset == _file_reader->size()) {
125
0
            LOG(WARNING) << "read delete bitmap failed because reach end of file=" << _path
126
0
                         << ", file size=" << _file_reader->size() << ", offset=" << offset
127
0
                         << ", delete_bitmap_len=" << delete_bitmap_len;
128
0
            return Status::InternalError(
129
0
                    "read delete bitmap failed from {} because reach end of file", _path);
130
0
        }
131
1
    }
132
    // 2. read delete bitmap
133
1
    std::string delete_bitmap_buf;
134
1
    {
135
1
        delete_bitmap_buf.resize(delete_bitmap_len);
136
1
        RETURN_IF_ERROR(_file_reader->read_at(
137
1
                offset, {delete_bitmap_buf.c_str(), delete_bitmap_len}, &bytes_read));
138
1
        offset += delete_bitmap_len;
139
1
        if (!delete_bitmap.ParseFromString(delete_bitmap_buf)) {
140
0
            LOG(WARNING) << "deserialize delete bitmap failed from file=" << _path
141
0
                         << ", file size=" << _file_reader->size()
142
0
                         << ", delete_bitmap_len=" << delete_bitmap_len
143
0
                         << ", bytes_read=" << bytes_read;
144
0
            return Status::InternalError("deserialize delete bitmap failed from {}", _path);
145
0
        }
146
1
    }
147
    // 3. checksum
148
1
    uint8_t checksum_len_buf[DeleteBitmapFileWriter::CHECKSUM_SIZE];
149
1
    RETURN_IF_ERROR(_file_reader->read_at(
150
1
            offset, {checksum_len_buf, DeleteBitmapFileWriter::CHECKSUM_SIZE}, &bytes_read));
151
1
    offset += DeleteBitmapFileWriter::CHECKSUM_SIZE;
152
1
    uint32_t checksum = decode_fixed32_le(checksum_len_buf);
153
1
    uint32_t computed_checksum = crc32c::Crc32c(delete_bitmap_buf.data(), delete_bitmap_len);
154
1
    if (computed_checksum != checksum) {
155
0
        return Status::InternalError("delete bitmap checksum failed from file=" + _path +
156
0
                                     ", computed checksum=" + std::to_string(computed_checksum) +
157
0
                                     ", expected=" + std::to_string(checksum));
158
0
    }
159
1
    return Status::OK();
160
1
}
161
162
#include "common/compile_check_end.h"
163
} // namespace doris