blob: 59f0c6c027470ecb4af6d354255bda41a9695943 [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_writer.h"
#include <crc32c/crc32c.h>
#include "cloud/config.h"
#include "io/fs/file_writer.h"
#include "io/fs/packed_file_writer.h"
namespace doris {
#include "common/compile_check_begin.h"
DeleteBitmapFileWriter::DeleteBitmapFileWriter(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) {}
DeleteBitmapFileWriter::DeleteBitmapFileWriter(int64_t tablet_id, const std::string& rowset_id,
std::optional<StorageResource>& storage_resource,
bool enable_packed_file, int64_t txn_id)
: _tablet_id(tablet_id),
_rowset_id(rowset_id),
_storage_resource(storage_resource),
_enable_packed_file(enable_packed_file),
_txn_id(txn_id) {}
DeleteBitmapFileWriter::~DeleteBitmapFileWriter() {}
Status DeleteBitmapFileWriter::init() {
#ifdef BE_TEST
_path = "./log/" + _rowset_id + "_delete_bitmap.db";
io::Path path = _path;
auto parent_path = path.parent_path();
bool exists = false;
RETURN_IF_ERROR(io::global_local_filesystem()->exists(parent_path, &exists));
if (!exists) {
RETURN_IF_ERROR(io::global_local_filesystem()->create_directory(parent_path));
}
RETURN_IF_ERROR(io::global_local_filesystem()->create_file(_path, &_file_writer));
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::FileWriterOptions opts;
if (_enable_packed_file) {
// Create underlying file writer
io::FileWriterPtr inner_writer;
// Disable write_file_cache for inner writer when using PackedFileWriter.
// Small files will be cached separately by PackedFileManager using the
// small file path as cache key.
opts.write_file_cache = false;
RETURN_IF_ERROR(_storage_resource->fs->create_file(_path, &inner_writer, &opts));
// Wrap with PackedFileWriter
io::PackedAppendContext append_info;
append_info.resource_id = _storage_resource->fs->id();
append_info.tablet_id = _tablet_id;
append_info.rowset_id = _rowset_id;
append_info.txn_id = _txn_id;
append_info.write_file_cache = false;
_file_writer = std::make_unique<io::PackedFileWriter>(std::move(inner_writer),
io::Path(_path), append_info);
} else {
RETURN_IF_ERROR(_storage_resource->fs->create_file(_path, &_file_writer, &opts));
}
return Status::OK();
}
Status DeleteBitmapFileWriter::close() {
if (!_file_writer) {
return Status::InternalError("fail to close delete bitmap file={} because writer is null",
_path);
}
auto st = _file_writer->close();
if (!st.ok()) {
LOG(WARNING) << "failed to close delete bitmap file=" << _path << ", st=" << st.to_string();
return st;
}
// Check if file was written to packed file
if (_enable_packed_file) {
auto* packed_writer = static_cast<io::PackedFileWriter*>(_file_writer.get());
io::PackedSliceLocation loc;
st = packed_writer->get_packed_slice_location(&loc);
if (!st.ok()) {
LOG(WARNING) << "failed to get packed slice location for delete bitmap file=" << _path
<< ", st=" << st.to_string();
return st;
}
if (!loc.packed_file_path.empty()) {
_is_packed = true;
_packed_location = loc;
}
}
return Status::OK();
}
Status DeleteBitmapFileWriter::get_packed_slice_location(io::PackedSliceLocation* location) const {
if (!_is_packed) {
return Status::InternalError("delete bitmap file is not packed");
}
*location = _packed_location;
return Status::OK();
}
Status DeleteBitmapFileWriter::write(const DeleteBitmapPB& delete_bitmap) {
if (delete_bitmap.rowset_ids_size() == 0) {
return Status::InternalError("empty delete bitmap for file={}", _path);
}
if (!_file_writer) {
return Status::InternalError("fail to write delete bitmap file={} because writer is null",
_path);
}
// 0. write magic
RETURN_IF_ERROR(_file_writer->append({DELETE_BITMAP_MAGIC, MAGIC_SIZE}));
// 1. write delete bitmap length
uint64_t delete_bitmap_len = delete_bitmap.ByteSizeLong();
uint8_t len_buf[LENGTH_SIZE];
encode_fixed64_le(len_buf, delete_bitmap_len);
RETURN_IF_ERROR(_file_writer->append({len_buf, LENGTH_SIZE}));
// 2. write delete bitmap
std::string content = delete_bitmap.SerializeAsString();
RETURN_IF_ERROR(_file_writer->append(content));
// 3. write checksum
uint8_t checksum_buf[CHECKSUM_SIZE];
uint32_t checksum = crc32c::Crc32c(content.data(), delete_bitmap_len);
encode_fixed32_le(checksum_buf, checksum);
RETURN_IF_ERROR(_file_writer->append({checksum_buf, CHECKSUM_SIZE}));
return Status::OK();
}
#include "common/compile_check_end.h"
} // namespace doris