| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| #include "cloud/delete_bitmap_file_reader.h" |
| |
| #include "cloud/delete_bitmap_file_writer.h" |
| #include "common/status.h" |
| #include "io/fs/file_reader.h" |
| #include "util/coding.h" |
| |
| namespace doris { |
| #include "common/compile_check_begin.h" |
| |
| DeleteBitmapFileReader::DeleteBitmapFileReader(int64_t tablet_id, const std::string& rowset_id, |
| std::optional<StorageResource>& storage_resource) |
| : _tablet_id(tablet_id), _rowset_id(rowset_id), _storage_resource(storage_resource) {} |
| |
| DeleteBitmapFileReader::~DeleteBitmapFileReader() = default; |
| |
| Status DeleteBitmapFileReader::init() { |
| #ifdef BE_TEST |
| _path = "./log/" + _rowset_id + "_delete_bitmap.db"; |
| bool exists = false; |
| RETURN_IF_ERROR(io::global_local_filesystem()->exists(_path, &exists)); |
| if (!exists) { |
| return Status::NotFound("{} doesn't exist", _path); |
| } |
| RETURN_IF_ERROR(io::global_local_filesystem()->open_file(_path, &_file_reader)); |
| return Status::OK(); |
| #endif |
| if (!_storage_resource) { |
| return Status::InternalError("invalid storage resource for tablet_id={}", _tablet_id); |
| } |
| _path = _storage_resource->remote_delete_bitmap_path(_tablet_id, _rowset_id); |
| io::FileReaderOptions opts; |
| return _storage_resource->fs->open_file(_path, &_file_reader, &opts); |
| } |
| |
| Status DeleteBitmapFileReader::close() { |
| if (_file_reader) { |
| return _file_reader->close(); |
| } |
| return Status::OK(); |
| } |
| |
| Status DeleteBitmapFileReader::read(DeleteBitmapPB& delete_bitmap) { |
| size_t bytes_read = 0; |
| size_t offset = 0; |
| // 0. read magic number |
| { |
| uint8_t magic_buf[DeleteBitmapFileWriter::MAGIC_SIZE]; |
| RETURN_IF_ERROR(_file_reader->read_at( |
| offset, {magic_buf, DeleteBitmapFileWriter::MAGIC_SIZE}, &bytes_read)); |
| offset += DeleteBitmapFileWriter::MAGIC_SIZE; |
| if (bytes_read != DeleteBitmapFileWriter::MAGIC_SIZE || |
| memcmp(magic_buf, DeleteBitmapFileWriter::DELETE_BITMAP_MAGIC, |
| DeleteBitmapFileWriter::MAGIC_SIZE) != 0) { |
| return Status::InternalError( |
| "read delete bitmap failed from {} because magic is not " |
| "matched", |
| _path); |
| } |
| } |
| // 1. read delete bitmap proto length |
| size_t delete_bitmap_len = 0; |
| { |
| uint8_t len_buf[DeleteBitmapFileWriter::LENGTH_SIZE]; |
| RETURN_IF_ERROR(_file_reader->read_at( |
| offset, {len_buf, DeleteBitmapFileWriter::LENGTH_SIZE}, &bytes_read)); |
| offset += DeleteBitmapFileWriter::LENGTH_SIZE; |
| delete_bitmap_len = decode_fixed64_le(len_buf); |
| if (delete_bitmap_len == 0) { |
| return Status::InternalError("read delete bitmap failed from {} because length is 0", |
| _path); |
| } |
| if (offset == _file_reader->size()) { |
| LOG(WARNING) << "read delete bitmap failed because reach end of file=" << _path |
| << ", file size=" << _file_reader->size() << ", offset=" << offset |
| << ", delete_bitmap_len=" << delete_bitmap_len; |
| return Status::InternalError( |
| "read delete bitmap failed from {} because reach end of file", _path); |
| } |
| } |
| // 2. read delete bitmap |
| std::string delete_bitmap_buf; |
| { |
| delete_bitmap_buf.resize(delete_bitmap_len); |
| RETURN_IF_ERROR(_file_reader->read_at( |
| offset, {delete_bitmap_buf.c_str(), delete_bitmap_len}, &bytes_read)); |
| offset += delete_bitmap_len; |
| if (!delete_bitmap.ParseFromString(delete_bitmap_buf)) { |
| LOG(WARNING) << "deserialize delete bitmap failed from file=" << _path |
| << ", file size=" << _file_reader->size() |
| << ", delete_bitmap_len=" << delete_bitmap_len |
| << ", bytes_read=" << bytes_read; |
| return Status::InternalError("deserialize delete bitmap failed from {}", _path); |
| } |
| } |
| // 3. checksum |
| uint8_t checksum_len_buf[DeleteBitmapFileWriter::CHECKSUM_SIZE]; |
| RETURN_IF_ERROR(_file_reader->read_at( |
| offset, {checksum_len_buf, DeleteBitmapFileWriter::CHECKSUM_SIZE}, &bytes_read)); |
| offset += DeleteBitmapFileWriter::CHECKSUM_SIZE; |
| uint32_t checksum = decode_fixed32_le(checksum_len_buf); |
| uint32_t computed_checksum = crc32c::Crc32c(delete_bitmap_buf.data(), delete_bitmap_len); |
| if (computed_checksum != checksum) { |
| return Status::InternalError("delete bitmap checksum failed from file=" + _path + |
| ", computed checksum=" + std::to_string(computed_checksum) + |
| ", expected=" + std::to_string(checksum)); |
| } |
| return Status::OK(); |
| } |
| |
| #include "common/compile_check_end.h" |
| } // namespace doris |