blob: 20b5f19f31c84f66b0720578a2066433ab2983f9 [file] [log] [blame]
// 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