From e79f0dc5328f28b2b3942e2cd0e9b0c1accca4a1 Mon Sep 17 00:00:00 2001 From: Nicole Mazzuca Date: Fri, 2 Aug 2019 16:49:45 -0700 Subject: [vcpkg] Make Filesystem::remove_all faster #7570 I added benchmarks to measure how fast the parallel remove_all code was -- it turns out, about 3x slower than stdfs::remove_all. Since this was the case, I removed all of the parallelism and rewrote it serially, and ended up about 30% faster than stdfs::remove_all (in addition to supporting symlinks). In addition, I did the following three orthogonal changes: - simplified the work queue, basing it on Billy O'Neal's idea - Fix warnings on older versions of compilers in tests, by splitting the pragmas out of pch.h. - Ran clang-format on some files In fixing up remove_all, the following changes were made: - On Windows, regular symlinks and directory symlinks are distinct; as an example, to remove directory symlinks (and junctions, for that matter), one must use RemoveDirectory. Only on Windows, I added new `file_type` and `file_status` types, with `file_type` including a new `directory_symlink` enumerator, and `file_status` being exactly the same as the old one except using the new `file_type`. On Unix, I didn't make that change since they don't make a distinction. - I added new `symlink_status` and `status` functions which use the new `file_status` on Windows. - I made `Filesystem::exists` call `fs::exists(status(p))`, as opposed to the old version which called `stdfs::exists` directly. - Added benchmarks to `vcpkg-test/files.cpp`. They test the performance of `remove_all` on small directories (~20 files), with symlinks and without, and on large directories (~2000 files), with symlinks and without. --- toolsrc/include/vcpkg-test/util.h | 78 ++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 26 deletions(-) (limited to 'toolsrc/include/vcpkg-test') diff --git a/toolsrc/include/vcpkg-test/util.h b/toolsrc/include/vcpkg-test/util.h index fa650abc8..8a458a3e5 100644 --- a/toolsrc/include/vcpkg-test/util.h +++ b/toolsrc/include/vcpkg-test/util.h @@ -1,42 +1,68 @@ +#include +#include + #include #include #include -namespace vcpkg::Test { +#define CHECK_EC(ec) \ + do \ + { \ + if (ec) \ + { \ + FAIL(ec.message()); \ + } \ + } while (0) -std::unique_ptr make_status_pgh(const char* name, - const char* depends = "", - const char* default_features = "", - const char* triplet = "x86-windows"); +namespace vcpkg::Test +{ + std::unique_ptr make_status_pgh(const char* name, + const char* depends = "", + const char* default_features = "", + const char* triplet = "x86-windows"); -std::unique_ptr make_status_feature_pgh(const char* name, - const char* feature, - const char* depends = "", - const char* triplet = "x86-windows"); + std::unique_ptr make_status_feature_pgh(const char* name, + const char* feature, + const char* depends = "", + const char* triplet = "x86-windows"); -vcpkg::PackageSpec unsafe_pspec(std::string name, vcpkg::Triplet t = vcpkg::Triplet::X86_WINDOWS); + vcpkg::PackageSpec unsafe_pspec(std::string name, vcpkg::Triplet t = vcpkg::Triplet::X86_WINDOWS); -template -T&& unwrap(vcpkg::ExpectedT&& p) -{ - REQUIRE(p.has_value()); - return std::move(*p.get()); -} + template + T&& unwrap(vcpkg::ExpectedT&& p) + { + REQUIRE(p.has_value()); + return std::move(*p.get()); + } -template -T&& unwrap(vcpkg::Optional&& opt) -{ - REQUIRE(opt.has_value()); - return std::move(*opt.get()); -} + template + T&& unwrap(vcpkg::Optional&& opt) + { + REQUIRE(opt.has_value()); + return std::move(*opt.get()); + } + + struct AllowSymlinks + { + enum Tag : bool + { + No = false, + Yes = true, + } tag; + + constexpr AllowSymlinks(Tag tag) noexcept : tag(tag) {} + + constexpr explicit AllowSymlinks(bool b) noexcept : tag(b ? Yes : No) {} -extern const bool SYMLINKS_ALLOWED; + constexpr operator bool() const noexcept { return tag == Yes; } + }; -extern const fs::path TEMPORARY_DIRECTORY; + AllowSymlinks can_create_symlinks() noexcept; -void create_symlink(const fs::path& file, const fs::path& target, std::error_code& ec); + const fs::path& base_temporary_directory() noexcept; -void create_directory_symlink(const fs::path& file, const fs::path& target, std::error_code& ec); + void create_symlink(const fs::path& file, const fs::path& target, std::error_code& ec); + void create_directory_symlink(const fs::path& file, const fs::path& target, std::error_code& ec); } -- cgit v1.2.3