diff --git a/include/dwarfs/reader/filesystem_v2.h b/include/dwarfs/reader/filesystem_v2.h index 60401428..ff284cd4 100644 --- a/include/dwarfs/reader/filesystem_v2.h +++ b/include/dwarfs/reader/filesystem_v2.h @@ -357,6 +357,10 @@ class filesystem_v2 { return impl_->get_block_category(block_number); } + void cache_blocks_by_category(std::string_view category) const { + return impl_->cache_blocks_by_category(category); + } + class impl { public: virtual ~impl() = default; @@ -452,6 +456,7 @@ class filesystem_v2 { virtual std::shared_ptr get_parser() const = 0; virtual std::optional get_block_category(size_t block_number) const = 0; + virtual void cache_blocks_by_category(std::string_view category) const = 0; }; private: diff --git a/include/dwarfs/reader/internal/inode_reader_v2.h b/include/dwarfs/reader/internal/inode_reader_v2.h index fd7a4886..75e47bfa 100644 --- a/include/dwarfs/reader/internal/inode_reader_v2.h +++ b/include/dwarfs/reader/internal/inode_reader_v2.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -100,6 +101,10 @@ class inode_reader_v2 { size_t num_blocks() const { return impl_->num_blocks(); } + void cache_blocks(std::span blocks) const { + impl_->cache_blocks(blocks); + } + class impl { public: virtual ~impl() = default; @@ -121,6 +126,7 @@ class inode_reader_v2 { virtual void set_num_workers(size_t num) = 0; virtual void set_cache_tidy_config(cache_tidy_config const& cfg) = 0; virtual size_t num_blocks() const = 0; + virtual void cache_blocks(std::span blocks) const = 0; }; private: diff --git a/include/dwarfs/reader/internal/metadata_v2.h b/include/dwarfs/reader/internal/metadata_v2.h index aea9dc6c..1874f63a 100644 --- a/include/dwarfs/reader/internal/metadata_v2.h +++ b/include/dwarfs/reader/internal/metadata_v2.h @@ -184,6 +184,11 @@ class metadata_v2 { return impl_->get_all_gids(); } + std::vector + get_block_numbers_by_category(std::string_view category) const { + return impl_->get_block_numbers_by_category(category); + } + class impl { public: virtual ~impl() = default; @@ -255,6 +260,9 @@ class metadata_v2 { virtual std::vector get_all_uids() const = 0; virtual std::vector get_all_gids() const = 0; + + virtual std::vector + get_block_numbers_by_category(std::string_view category) const = 0; }; private: diff --git a/src/reader/filesystem_v2.cpp b/src/reader/filesystem_v2.cpp index 4d12f76c..a2f7e620 100644 --- a/src/reader/filesystem_v2.cpp +++ b/src/reader/filesystem_v2.cpp @@ -312,6 +312,10 @@ class filesystem_ final : public filesystem_v2::impl { return meta_.get_block_category(block_no); } + void cache_blocks_by_category(std::string_view category) const override { + ir_.cache_blocks(meta_.get_block_numbers_by_category(category)); + } + private: filesystem_info const* get_info(fsinfo_options const& opts) const; void check_section(fs_section const& section) const; diff --git a/src/reader/internal/block_cache.cpp b/src/reader/internal/block_cache.cpp index ef81557e..2d701453 100644 --- a/src/reader/internal/block_cache.cpp +++ b/src/reader/internal/block_cache.cpp @@ -722,6 +722,8 @@ class block_cache_ final : public block_cache::impl { block->touch(); } + LOG_VERBOSE << "inserting block " << block_no << " into cache"; + cache_.set(block_no, std::move(block)); } } diff --git a/src/reader/internal/inode_reader_v2.cpp b/src/reader/internal/inode_reader_v2.cpp index cf8d6162..6b352a68 100644 --- a/src/reader/internal/inode_reader_v2.cpp +++ b/src/reader/internal/inode_reader_v2.cpp @@ -152,6 +152,12 @@ class inode_reader_ final : public inode_reader_v2::impl { } size_t num_blocks() const override { return cache_.block_count(); } + void cache_blocks(std::span blocks) const override { + for (auto b : blocks) { + cache_.get(b, 0, 1); + } + } + private: using offset_cache_type = basic_offset_cache get_all_uids() const override; std::vector get_all_gids() const override; + std::vector + get_block_numbers_by_category(std::string_view category) const override; + private: template using set_type = folly::F14ValueSet; @@ -2203,6 +2206,35 @@ std::vector metadata_::get_all_gids() const { return rv; } +template +std::vector metadata_::get_block_numbers_by_category( + std::string_view category) const { + std::vector rv; + + if (auto catnames = meta_.category_names()) { + if (auto categories = meta_.block_categories()) { + std::optional category_num; + + for (size_t catnum = 0; catnum < catnames.value().size(); ++catnum) { + if (catnames.value()[catnum] == category) { + category_num = catnum; + break; + } + } + + if (category_num) { + for (size_t blknum = 0; blknum < categories.value().size(); ++blknum) { + if (categories.value()[blknum] == *category_num) { + rv.push_back(blknum); + } + } + } + } + } + + return rv; +} + metadata_v2::metadata_v2( logger& lgr, std::span schema, std::span data, metadata_options const& options, int inode_offset,