[libcxx-commits] [libcxx] [libcxx] Cache file attributes during directory iteration. (PR #93316)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Aug 30 07:08:41 PDT 2024
================
@@ -0,0 +1,187 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: can-create-symlinks
+// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: no-filesystem
+// UNSUPPORTED: availability-filesystem-missing
+
+// <filesystem>
+
+// recursive_directory_iterator
+
+#include <filesystem>
+#include <type_traits>
+#include <set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.h"
+namespace fs = std::filesystem;
+using namespace fs;
+
+#if defined(_WIN32)
+static void set_last_write_time_in_iteration(const fs::path& dir) {
+ // Windows can postpone updating last write time for file especially for
+ // directory because last write time of directory depends of its childs.
+ // See
+ // https://learn.microsoft.com/en-us/windows/win32/sysinfo/file-times
+ // To force updating file entries calls "last_write_time" with own value.
+ const recursive_directory_iterator end_it{};
+
+ std::error_code ec;
+ recursive_directory_iterator it(dir, ec);
+ assert(!ec);
+
+ file_time_type now_time = file_time_type::clock::now();
+ for (; it != end_it; ++it) {
+ const path entry = *it;
+ last_write_time(entry, now_time, ec);
+ assert(!ec);
+ }
+
+ assert(it == end_it);
+}
+
+struct directory_entry_and_values {
+ directory_entry entry;
+
+ file_status symlink_status;
+ file_status status;
+ std::uintmax_t file_size;
+ file_time_type last_write_time;
+};
+
+std::vector<directory_entry_and_values> get_directory_entries_for(const path& dir, const std::set<path>& dir_contents) {
+ const recursive_directory_iterator end_it{};
+
+ std::error_code ec;
+ recursive_directory_iterator it(dir, ec);
+ assert(!ec);
+
+ std::vector<directory_entry_and_values> dir_entries;
+ std::set<path> unseen_entries = dir_contents;
+ while (!unseen_entries.empty()) {
+ assert(it != end_it);
+ const directory_entry& entry = *it;
+
+ assert(unseen_entries.erase(entry.path()) == 1);
+
+ dir_entries.push_back(directory_entry_and_values{
+ .entry = entry,
+ .symlink_status = entry.symlink_status(),
+ .status = entry.status(),
+ .file_size = entry.is_regular_file() ? entry.file_size() : 0,
+ .last_write_time = entry.last_write_time()});
+
+ recursive_directory_iterator& it_ref = it.increment(ec);
+ assert(!ec);
+ assert(&it_ref == &it);
+ }
+ return dir_entries;
+}
+#endif
----------------
ldionne wrote:
```suggestion
#endif // _WIN32
```
https://github.com/llvm/llvm-project/pull/93316
More information about the libcxx-commits
mailing list