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.
This commit is contained in:
Marcus Holland-Moritz 2021-02-28 21:20:24 +01:00
parent f070bf8277
commit d19651ac3f
4 changed files with 51 additions and 8 deletions

View File

@ -83,6 +83,10 @@ class filesystem_v2 {
impl_->walk(func);
}
void walk(std::function<void(entry_view, directory_view)> const& func) const {
impl_->walk(func);
}
std::optional<entry_view> 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<void(entry_view)> const& func) const = 0;
virtual void
walk(std::function<void(entry_view, directory_view)> const& func) const = 0;
virtual std::optional<entry_view> find(const char* path) const = 0;
virtual std::optional<entry_view> find(int inode) const = 0;
virtual std::optional<entry_view>

View File

@ -87,6 +87,10 @@ class metadata_v2 {
impl_->walk(func);
}
void walk(std::function<void(entry_view, directory_view)> const& func) const {
impl_->walk(func);
}
std::optional<entry_view> 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<void(entry_view)> const& func) const = 0;
virtual void
walk(std::function<void(entry_view, directory_view)> const& func) const = 0;
virtual std::optional<entry_view> find(const char* path) const = 0;
virtual std::optional<entry_view> find(int inode) const = 0;

View File

@ -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<void(entry_view)> const& func) const override;
void walk(std::function<void(entry_view, directory_view)> const& func)
const override;
std::optional<entry_view> find(const char* path) const override;
std::optional<entry_view> find(int inode) const override;
std::optional<entry_view> find(int inode, const char* name) const override;
@ -281,6 +283,12 @@ void filesystem_<LoggerPolicy>::walk(
meta_.walk(func);
}
template <typename LoggerPolicy>
void filesystem_<LoggerPolicy>::walk(
std::function<void(entry_view, directory_view)> const& func) const {
meta_.walk(func);
}
template <typename LoggerPolicy>
std::optional<entry_view>
filesystem_<LoggerPolicy>::find(const char* path) const {

View File

@ -179,6 +179,8 @@ class metadata_ : public metadata_v2::impl {
bool empty() const override { return data_.empty(); }
void walk(std::function<void(entry_view)> const& func) const override;
void walk(std::function<void(entry_view, directory_view)> const& func)
const override;
std::optional<entry_view> find(const char* path) const override;
std::optional<entry_view> find(int inode) const override;
@ -331,8 +333,21 @@ class metadata_ : public metadata_v2::impl {
}
}
void walk(entry_view entry, std::unordered_set<int>& seen,
std::function<void(entry_view)> const& func) const;
static void walk_call(std::function<void(entry_view)> const& func,
entry_view entry, directory_view) {
func(entry);
}
static void
walk_call(std::function<void(entry_view, directory_view)> const& func,
entry_view entry, directory_view dir) {
func(entry, dir);
}
template <typename Signature>
void
walk(directory_view parent, entry_view entry, std::unordered_set<int>& seen,
std::function<Signature> const& func) const;
std::optional<entry_view> get_entry(int inode) const {
inode -= inode_offset_;
@ -572,10 +587,11 @@ std::string metadata_<LoggerPolicy>::modestring(uint16_t mode) const {
}
template <typename LoggerPolicy>
void metadata_<LoggerPolicy>::walk(
entry_view entry, std::unordered_set<int>& seen,
std::function<void(entry_view)> const& func) const {
func(entry);
template <typename Signature>
void metadata_<LoggerPolicy>::walk(directory_view parent, entry_view entry,
std::unordered_set<int>& seen,
std::function<Signature> 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_<LoggerPolicy>::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 <typename LoggerPolicy>
void metadata_<LoggerPolicy>::walk(
std::function<void(entry_view)> const& func) const {
std::unordered_set<int> seen;
walk(root_, seen, func);
walk(make_directory_view(root_), root_, seen, func);
}
template <typename LoggerPolicy>
void metadata_<LoggerPolicy>::walk(
std::function<void(entry_view, directory_view)> const& func) const {
std::unordered_set<int> seen;
walk(make_directory_view(root_), root_, seen, func);
}
template <typename LoggerPolicy>