From ebb836d499e8395bb1f6cb18de09346fc7e761ac Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Fri, 2 May 2025 17:43:02 +0000 Subject: [PATCH] Use transparent comparators for std::set (NFC) This patch finally applies the transition to std::less<>, which is a transparent comparator. There's no functional change and string lookups in sets are now more efficient and don't produce temporaries (e.g. set.find(std::string_view{"key"})). --- .../include/nix/store/common-protocol-impl.hh | 4 ++-- .../include/nix/store/common-protocol.hh | 6 ++--- src/libstore/include/nix/store/derivations.hh | 2 +- .../store/length-prefixed-protocol-helper.hh | 20 ++++++++--------- .../include/nix/store/outputs-spec.hh | 16 +++++++++----- .../include/nix/store/serve-protocol-impl.hh | 4 +++- .../include/nix/store/serve-protocol.hh | 6 ++--- .../include/nix/store/worker-protocol-impl.hh | 4 +++- .../include/nix/store/worker-protocol.hh | 8 +++---- src/libutil/include/nix/util/json-utils.hh | 4 ++-- src/libutil/include/nix/util/topo-sort.hh | 10 ++++----- src/libutil/include/nix/util/types.hh | 22 +++++++++++++++++-- 12 files changed, 66 insertions(+), 40 deletions(-) diff --git a/src/libstore/include/nix/store/common-protocol-impl.hh b/src/libstore/include/nix/store/common-protocol-impl.hh index 171b4c6a5..18e63ac33 100644 --- a/src/libstore/include/nix/store/common-protocol-impl.hh +++ b/src/libstore/include/nix/store/common-protocol-impl.hh @@ -25,11 +25,11 @@ namespace nix { LengthPrefixedProtoHelper::write(store, conn, t); \ } +#define COMMA_ , COMMON_USE_LENGTH_PREFIX_SERIALISER(template, std::vector) -COMMON_USE_LENGTH_PREFIX_SERIALISER(template, std::set) +COMMON_USE_LENGTH_PREFIX_SERIALISER(template, std::set) COMMON_USE_LENGTH_PREFIX_SERIALISER(template, std::tuple) -#define COMMA_ , COMMON_USE_LENGTH_PREFIX_SERIALISER( template, std::map) diff --git a/src/libstore/include/nix/store/common-protocol.hh b/src/libstore/include/nix/store/common-protocol.hh index b464cda67..7887120b5 100644 --- a/src/libstore/include/nix/store/common-protocol.hh +++ b/src/libstore/include/nix/store/common-protocol.hh @@ -72,14 +72,14 @@ DECLARE_COMMON_SERIALISER(DrvOutput); template<> DECLARE_COMMON_SERIALISER(Realisation); +#define COMMA_ , template DECLARE_COMMON_SERIALISER(std::vector); -template -DECLARE_COMMON_SERIALISER(std::set); +template +DECLARE_COMMON_SERIALISER(std::set); template DECLARE_COMMON_SERIALISER(std::tuple); -#define COMMA_ , template DECLARE_COMMON_SERIALISER(std::map); #undef COMMA_ diff --git a/src/libstore/include/nix/store/derivations.hh b/src/libstore/include/nix/store/derivations.hh index 01ff337f6..46a9e2d02 100644 --- a/src/libstore/include/nix/store/derivations.hh +++ b/src/libstore/include/nix/store/derivations.hh @@ -343,7 +343,7 @@ struct Derivation : BasicDerivation /** * inputs that are sub-derivations */ - DerivedPathMap> inputDrvs; + DerivedPathMap>> inputDrvs; /** * Print a derivation. diff --git a/src/libstore/include/nix/store/length-prefixed-protocol-helper.hh b/src/libstore/include/nix/store/length-prefixed-protocol-helper.hh index 664841aae..a83635aa4 100644 --- a/src/libstore/include/nix/store/length-prefixed-protocol-helper.hh +++ b/src/libstore/include/nix/store/length-prefixed-protocol-helper.hh @@ -52,8 +52,10 @@ struct LengthPrefixedProtoHelper; template LENGTH_PREFIXED_PROTO_HELPER(Inner, std::vector); -template -LENGTH_PREFIXED_PROTO_HELPER(Inner, std::set); +#define COMMA_ , +template +LENGTH_PREFIXED_PROTO_HELPER(Inner, std::set); +#undef COMMA_ template LENGTH_PREFIXED_PROTO_HELPER(Inner, std::tuple); @@ -86,12 +88,11 @@ LengthPrefixedProtoHelper>::write( } } -template -std::set -LengthPrefixedProtoHelper>::read( +template +std::set LengthPrefixedProtoHelper>::read( const StoreDirConfig & store, typename Inner::ReadConn conn) { - std::set resSet; + std::set resSet; auto size = readNum(conn.from); while (size--) { resSet.insert(S::read(store, conn)); @@ -99,10 +100,9 @@ LengthPrefixedProtoHelper>::read( return resSet; } -template -void -LengthPrefixedProtoHelper>::write( - const StoreDirConfig & store, typename Inner::WriteConn conn, const std::set & resSet) +template +void LengthPrefixedProtoHelper>::write( + const StoreDirConfig & store, typename Inner::WriteConn conn, const std::set & resSet) { conn.to << resSet.size(); for (auto & key : resSet) { diff --git a/src/libstore/include/nix/store/outputs-spec.hh b/src/libstore/include/nix/store/outputs-spec.hh index b89f425c2..b47f26542 100644 --- a/src/libstore/include/nix/store/outputs-spec.hh +++ b/src/libstore/include/nix/store/outputs-spec.hh @@ -27,20 +27,24 @@ struct OutputsSpec { /** * A non-empty set of outputs, specified by name */ - struct Names : std::set { - using std::set::set; + struct Names : std::set> { + private: + using BaseType = std::set>; + + public: + using BaseType::BaseType; /* These need to be "inherited manually" */ - Names(const std::set & s) - : std::set(s) + Names(const BaseType & s) + : BaseType(s) { assert(!empty()); } /** * Needs to be "inherited manually" */ - Names(std::set && s) - : std::set(s) + Names(BaseType && s) + : BaseType(std::move(s)) { assert(!empty()); } /* This set should always be non-empty, so we delete this diff --git a/src/libstore/include/nix/store/serve-protocol-impl.hh b/src/libstore/include/nix/store/serve-protocol-impl.hh index 769b9ae2b..4ab164721 100644 --- a/src/libstore/include/nix/store/serve-protocol-impl.hh +++ b/src/libstore/include/nix/store/serve-protocol-impl.hh @@ -26,7 +26,9 @@ namespace nix { } SERVE_USE_LENGTH_PREFIX_SERIALISER(template, std::vector) -SERVE_USE_LENGTH_PREFIX_SERIALISER(template, std::set) +#define COMMA_ , +SERVE_USE_LENGTH_PREFIX_SERIALISER(template, std::set) +#undef COMMA_ SERVE_USE_LENGTH_PREFIX_SERIALISER(template, std::tuple) #define SERVE_USE_LENGTH_PREFIX_SERIALISER_COMMA , diff --git a/src/libstore/include/nix/store/serve-protocol.hh b/src/libstore/include/nix/store/serve-protocol.hh index 76f0ecd49..6f6bf6b60 100644 --- a/src/libstore/include/nix/store/serve-protocol.hh +++ b/src/libstore/include/nix/store/serve-protocol.hh @@ -180,12 +180,12 @@ DECLARE_SERVE_SERIALISER(ServeProto::BuildOptions); template DECLARE_SERVE_SERIALISER(std::vector); -template -DECLARE_SERVE_SERIALISER(std::set); +#define COMMA_ , +template +DECLARE_SERVE_SERIALISER(std::set); template DECLARE_SERVE_SERIALISER(std::tuple); -#define COMMA_ , template DECLARE_SERVE_SERIALISER(std::map); #undef COMMA_ diff --git a/src/libstore/include/nix/store/worker-protocol-impl.hh b/src/libstore/include/nix/store/worker-protocol-impl.hh index 337c245e2..908a9323e 100644 --- a/src/libstore/include/nix/store/worker-protocol-impl.hh +++ b/src/libstore/include/nix/store/worker-protocol-impl.hh @@ -26,7 +26,9 @@ namespace nix { } WORKER_USE_LENGTH_PREFIX_SERIALISER(template, std::vector) -WORKER_USE_LENGTH_PREFIX_SERIALISER(template, std::set) +#define COMMA_ , +WORKER_USE_LENGTH_PREFIX_SERIALISER(template, std::set) +#undef COMMA_ WORKER_USE_LENGTH_PREFIX_SERIALISER(template, std::tuple) #define WORKER_USE_LENGTH_PREFIX_SERIALISER_COMMA , diff --git a/src/libstore/include/nix/store/worker-protocol.hh b/src/libstore/include/nix/store/worker-protocol.hh index f96d41c71..1b188806d 100644 --- a/src/libstore/include/nix/store/worker-protocol.hh +++ b/src/libstore/include/nix/store/worker-protocol.hh @@ -135,7 +135,7 @@ struct WorkerProto } using Feature = std::string; - using FeatureSet = std::set; + using FeatureSet = std::set>; static const FeatureSet allFeatures; }; @@ -273,12 +273,12 @@ DECLARE_WORKER_SERIALISER(WorkerProto::ClientHandshakeInfo); template DECLARE_WORKER_SERIALISER(std::vector); -template -DECLARE_WORKER_SERIALISER(std::set); +#define COMMA_ , +template +DECLARE_WORKER_SERIALISER(std::set); template DECLARE_WORKER_SERIALISER(std::tuple); -#define COMMA_ , template DECLARE_WORKER_SERIALISER(std::map); #undef COMMA_ diff --git a/src/libutil/include/nix/util/json-utils.hh b/src/libutil/include/nix/util/json-utils.hh index bcae46a0a..37f4d58f8 100644 --- a/src/libutil/include/nix/util/json-utils.hh +++ b/src/libutil/include/nix/util/json-utils.hh @@ -90,8 +90,8 @@ struct json_avoids_null> : std::true_type {}; template struct json_avoids_null> : std::true_type {}; -template -struct json_avoids_null> : std::true_type {}; +template +struct json_avoids_null> : std::true_type {}; template struct json_avoids_null> : std::true_type {}; diff --git a/src/libutil/include/nix/util/topo-sort.hh b/src/libutil/include/nix/util/topo-sort.hh index 77a9ce421..6ba6fda71 100644 --- a/src/libutil/include/nix/util/topo-sort.hh +++ b/src/libutil/include/nix/util/topo-sort.hh @@ -5,13 +5,13 @@ namespace nix { -template -std::vector topoSort(std::set items, - std::function(const T &)> getChildren, +template +std::vector topoSort(std::set items, + std::function(const T &)> getChildren, std::function makeCycleError) { std::vector sorted; - std::set visited, parents; + decltype(items) visited, parents; std::function dfsVisit; @@ -21,7 +21,7 @@ std::vector topoSort(std::set items, if (!visited.insert(path).second) return; parents.insert(path); - std::set references = getChildren(path); + auto references = getChildren(path); for (auto & i : references) /* Don't traverse into items that don't exist in our starting set. */ diff --git a/src/libutil/include/nix/util/types.hh b/src/libutil/include/nix/util/types.hh index 9f5c75827..5139256ca 100644 --- a/src/libutil/include/nix/util/types.hh +++ b/src/libutil/include/nix/util/types.hh @@ -12,17 +12,35 @@ namespace nix { typedef std::list Strings; -typedef std::set StringSet; typedef std::map StringMap; typedef std::map StringPairs; +/** + * Alias to ordered set container with transparent comparator. + * + * Used instead of std::set to use C++14 N3657 [1] + * heterogenous lookup consistently across the whole codebase. + * Transparent comparators get rid of creation of unnecessary + * temporary variables when looking up keys by `std::string_view` + * or C-style `const char *` strings. + * + * [1]: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3657.htm + */ +using StringSet = std::set>; + /** * Paths are just strings. */ typedef std::string Path; typedef std::string_view PathView; typedef std::list Paths; -typedef std::set PathSet; + +/** + * Alias to an ordered set of `Path`s. Uses transparent comparator. + * + * @see StringSet + */ +using PathSet = std::set>; typedef std::vector> Headers;