From d19651ac3faf6ca46eb2858306473c4f1d60e877 Mon Sep 17 00:00:00 2001 From: Marcus Holland-Moritz Date: Sun, 28 Feb 2021 21:20:24 +0100 Subject: [PATCH] Allow walking filesystem with entry + directory views An entry by itself has no way of knowing which directory it belongs to. The new overload allows to also have access to the directory that the entry belongs to. --- include/dwarfs/filesystem_v2.h | 6 ++++++ include/dwarfs/metadata_v2.h | 6 ++++++ src/dwarfs/filesystem_v2.cpp | 8 +++++++ src/dwarfs/metadata_v2.cpp | 39 +++++++++++++++++++++++++++------- 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/include/dwarfs/filesystem_v2.h b/include/dwarfs/filesystem_v2.h index 17349563..348a0de1 100644 --- a/include/dwarfs/filesystem_v2.h +++ b/include/dwarfs/filesystem_v2.h @@ -83,6 +83,10 @@ class filesystem_v2 { impl_->walk(func); } + void walk(std::function const& func) const { + impl_->walk(func); + } + std::optional find(const char* path) const { return impl_->find(path); } @@ -141,6 +145,8 @@ class filesystem_v2 { virtual folly::dynamic metadata_as_dynamic() const = 0; virtual std::string serialize_metadata_as_json(bool simple) const = 0; virtual void walk(std::function const& func) const = 0; + virtual void + walk(std::function const& func) const = 0; virtual std::optional find(const char* path) const = 0; virtual std::optional find(int inode) const = 0; virtual std::optional diff --git a/include/dwarfs/metadata_v2.h b/include/dwarfs/metadata_v2.h index e68191d6..ed865d31 100644 --- a/include/dwarfs/metadata_v2.h +++ b/include/dwarfs/metadata_v2.h @@ -87,6 +87,10 @@ class metadata_v2 { impl_->walk(func); } + void walk(std::function const& func) const { + impl_->walk(func); + } + std::optional find(const char* path) const { return impl_->find(path); } @@ -152,6 +156,8 @@ class metadata_v2 { virtual bool empty() const = 0; virtual void walk(std::function const& func) const = 0; + virtual void + walk(std::function const& func) const = 0; virtual std::optional find(const char* path) const = 0; virtual std::optional find(int inode) const = 0; diff --git a/src/dwarfs/filesystem_v2.cpp b/src/dwarfs/filesystem_v2.cpp index e92fe11f..659f695b 100644 --- a/src/dwarfs/filesystem_v2.cpp +++ b/src/dwarfs/filesystem_v2.cpp @@ -183,6 +183,8 @@ class filesystem_ : public filesystem_v2::impl { folly::dynamic metadata_as_dynamic() const override; std::string serialize_metadata_as_json(bool simple) const override; void walk(std::function const& func) const override; + void walk(std::function const& func) + const override; std::optional find(const char* path) const override; std::optional find(int inode) const override; std::optional find(int inode, const char* name) const override; @@ -281,6 +283,12 @@ void filesystem_::walk( meta_.walk(func); } +template +void filesystem_::walk( + std::function const& func) const { + meta_.walk(func); +} + template std::optional filesystem_::find(const char* path) const { diff --git a/src/dwarfs/metadata_v2.cpp b/src/dwarfs/metadata_v2.cpp index 93fef80a..ddddc74e 100644 --- a/src/dwarfs/metadata_v2.cpp +++ b/src/dwarfs/metadata_v2.cpp @@ -179,6 +179,8 @@ class metadata_ : public metadata_v2::impl { bool empty() const override { return data_.empty(); } void walk(std::function const& func) const override; + void walk(std::function const& func) + const override; std::optional find(const char* path) const override; std::optional find(int inode) const override; @@ -331,8 +333,21 @@ class metadata_ : public metadata_v2::impl { } } - void walk(entry_view entry, std::unordered_set& seen, - std::function const& func) const; + static void walk_call(std::function const& func, + entry_view entry, directory_view) { + func(entry); + } + + static void + walk_call(std::function const& func, + entry_view entry, directory_view dir) { + func(entry, dir); + } + + template + void + walk(directory_view parent, entry_view entry, std::unordered_set& seen, + std::function const& func) const; std::optional get_entry(int inode) const { inode -= inode_offset_; @@ -572,10 +587,11 @@ std::string metadata_::modestring(uint16_t mode) const { } template -void metadata_::walk( - entry_view entry, std::unordered_set& seen, - std::function const& func) const { - func(entry); +template +void metadata_::walk(directory_view parent, entry_view entry, + std::unordered_set& seen, + std::function const& func) const { + walk_call(func, entry, parent); if (S_ISDIR(entry.mode())) { auto inode = entry.inode(); if (!seen.emplace(inode).second) { @@ -583,7 +599,7 @@ void metadata_::walk( } auto dir = make_directory_view(entry); for (auto cur : dir.entry_range()) { - walk(make_entry_view(cur), seen, func); + walk(dir, make_entry_view(cur), seen, func); } seen.erase(inode); } @@ -593,7 +609,14 @@ template void metadata_::walk( std::function const& func) const { std::unordered_set seen; - walk(root_, seen, func); + walk(make_directory_view(root_), root_, seen, func); +} + +template +void metadata_::walk( + std::function const& func) const { + std::unordered_set seen; + walk(make_directory_view(root_), root_, seen, func); } template