diff --git a/cmake/libdwarfs.cmake b/cmake/libdwarfs.cmake index 4b1a04bf..e84b838d 100644 --- a/cmake/libdwarfs.cmake +++ b/cmake/libdwarfs.cmake @@ -46,6 +46,7 @@ add_library( src/util.cpp src/varint.cpp src/vector_byte_buffer.cpp + src/vector_byte_buffer_factory.cpp src/xattr.cpp src/internal/features.cpp diff --git a/include/dwarfs/block_compressor.h b/include/dwarfs/block_compressor.h index 29761c58..0f69f89a 100644 --- a/include/dwarfs/block_compressor.h +++ b/include/dwarfs/block_compressor.h @@ -36,6 +36,7 @@ #include #include +#include #include #include @@ -112,6 +113,7 @@ class block_decompressor { block_decompressor(compression_type type, std::span data); shared_byte_buffer start_decompression(mutable_byte_buffer target); + shared_byte_buffer start_decompression(byte_buffer_factory const& bbf); bool decompress_frame(size_t frame_size = BUFSIZ) { return impl_->decompress_frame(frame_size); diff --git a/include/dwarfs/byte_buffer_factory.h b/include/dwarfs/byte_buffer_factory.h new file mode 100644 index 00000000..1fb9074d --- /dev/null +++ b/include/dwarfs/byte_buffer_factory.h @@ -0,0 +1,54 @@ +/* vim:set ts=2 sw=2 sts=2 et: */ +/** + * \author Marcus Holland-Moritz (github@mhxnet.de) + * \copyright Copyright (c) Marcus Holland-Moritz + * + * This file is part of dwarfs. + * + * dwarfs is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * dwarfs is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with dwarfs. If not, see . + */ + +#pragma once + +#include + +#include + +namespace dwarfs { + +class byte_buffer_factory_interface { + public: + virtual ~byte_buffer_factory_interface() = default; + + virtual mutable_byte_buffer + create_mutable_fixed_reserve(size_t size) const = 0; +}; + +class byte_buffer_factory { + public: + byte_buffer_factory() = default; + + explicit byte_buffer_factory( + std::shared_ptr impl) + : impl_{std::move(impl)} {} + + mutable_byte_buffer create_mutable_fixed_reserve(size_t size) const { + return impl_->create_mutable_fixed_reserve(size); + } + + private: + std::shared_ptr impl_; +}; + +} // namespace dwarfs diff --git a/include/dwarfs/reader/internal/cached_block.h b/include/dwarfs/reader/internal/cached_block.h index 10365c73..46e193f2 100644 --- a/include/dwarfs/reader/internal/cached_block.h +++ b/include/dwarfs/reader/internal/cached_block.h @@ -28,6 +28,7 @@ namespace dwarfs { +class byte_buffer_factory; class logger; class mmif; @@ -43,7 +44,8 @@ class cached_block { public: static std::unique_ptr create(logger& lgr, dwarfs::internal::fs_section const& b, - std::shared_ptr mm, bool release, bool disable_integrity_check); + std::shared_ptr mm, byte_buffer_factory const& bbf, bool release, + bool disable_integrity_check); virtual ~cached_block() = default; diff --git a/include/dwarfs/vector_byte_buffer_factory.h b/include/dwarfs/vector_byte_buffer_factory.h new file mode 100644 index 00000000..22a56cba --- /dev/null +++ b/include/dwarfs/vector_byte_buffer_factory.h @@ -0,0 +1,34 @@ +/* vim:set ts=2 sw=2 sts=2 et: */ +/** + * \author Marcus Holland-Moritz (github@mhxnet.de) + * \copyright Copyright (c) Marcus Holland-Moritz + * + * This file is part of dwarfs. + * + * dwarfs is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * dwarfs is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with dwarfs. If not, see . + */ + +#pragma once + +#include +#include + +namespace dwarfs { + +class vector_byte_buffer_factory { + public: + static byte_buffer_factory create(); +}; + +} // namespace dwarfs diff --git a/src/block_compressor.cpp b/src/block_compressor.cpp index 19fd0830..e0f5e2b3 100644 --- a/src/block_compressor.cpp +++ b/src/block_compressor.cpp @@ -63,6 +63,12 @@ block_decompressor::start_decompression(mutable_byte_buffer target) { return target.share(); } +shared_byte_buffer +block_decompressor::start_decompression(byte_buffer_factory const& bbf) { + auto target = bbf.create_mutable_fixed_reserve(impl_->uncompressed_size()); + return start_decompression(target); +} + compression_registry& compression_registry::instance() { static compression_registry the_instance; return the_instance; diff --git a/src/reader/internal/block_cache.cpp b/src/reader/internal/block_cache.cpp index 5a69806c..14dc6c8f 100644 --- a/src/reader/internal/block_cache.cpp +++ b/src/reader/internal/block_cache.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -223,6 +224,7 @@ class block_cache_ final : public block_cache::impl { [[maybe_unused]]) : cache_(0) , mm_(std::move(mm)) + , buffer_factory_{vector_byte_buffer_factory::create()} , LOG_PROXY_INIT(lgr) // clang-format off PERFMON_CLS_PROXY_INIT(perfmon, "block_cache") @@ -569,7 +571,8 @@ class block_cache_ final : public block_cache::impl { try { std::shared_ptr block = cached_block::create( LOG_GET_LOGGER, DWARFS_NOTHROW(block_.at(block_no)), mm_, - options_.mm_release, options_.disable_block_integrity_check); + buffer_factory_, options_.mm_release, + options_.disable_block_integrity_check); blocks_created_.fetch_add(1, std::memory_order_relaxed); // Make a new set for the block @@ -804,6 +807,7 @@ class block_cache_ final : public block_cache::impl { mutable worker_group wg_; std::vector block_; std::shared_ptr mm_; + byte_buffer_factory buffer_factory_; LOG_PROXY_DECL(LoggerPolicy); PERFMON_CLS_PROXY_DECL PERFMON_CLS_TIMER_DECL(get) diff --git a/src/reader/internal/cached_block.cpp b/src/reader/internal/cached_block.cpp index 2020f984..81ed088d 100644 --- a/src/reader/internal/cached_block.cpp +++ b/src/reader/internal/cached_block.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -46,10 +45,11 @@ class cached_block_ final : public cached_block { static inline std::atomic instance_count_{0}; cached_block_(logger& lgr, fs_section const& b, std::shared_ptr mm, - bool release, bool disable_integrity_check) + byte_buffer_factory const& buffer_factory, bool release, + bool disable_integrity_check) : decompressor_{std::make_unique( b.compression(), mm->span(b.start(), b.length()))} - , data_{decompressor_->start_decompression(vector_byte_buffer::create())} + , data_{decompressor_->start_decompression(buffer_factory)} , mm_(std::move(mm)) , section_(b) , LOG_PROXY_INIT(lgr) @@ -158,10 +158,11 @@ class cached_block_ final : public cached_block { std::unique_ptr cached_block::create(logger& lgr, fs_section const& b, std::shared_ptr mm, - bool release, bool disable_integrity_check) { + byte_buffer_factory const& bbf, bool release, + bool disable_integrity_check) { return make_unique_logging_object( - lgr, b, std::move(mm), release, disable_integrity_check); + lgr, b, std::move(mm), bbf, release, disable_integrity_check); } } // namespace dwarfs::reader::internal diff --git a/src/vector_byte_buffer_factory.cpp b/src/vector_byte_buffer_factory.cpp new file mode 100644 index 00000000..876e35a4 --- /dev/null +++ b/src/vector_byte_buffer_factory.cpp @@ -0,0 +1,42 @@ +/* vim:set ts=2 sw=2 sts=2 et: */ +/** + * \author Marcus Holland-Moritz (github@mhxnet.de) + * \copyright Copyright (c) Marcus Holland-Moritz + * + * This file is part of dwarfs. + * + * dwarfs is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * dwarfs is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with dwarfs. If not, see . + */ + +#include + +namespace dwarfs { + +namespace { + +class vector_byte_buffer_factory_impl : public byte_buffer_factory_interface { + public: + mutable_byte_buffer create_mutable_fixed_reserve(size_t size) const override { + return vector_byte_buffer::create_reserve(size); + } +}; + +} // namespace + +byte_buffer_factory vector_byte_buffer_factory::create() { + return byte_buffer_factory{ + std::make_shared()}; +} + +} // namespace dwarfs