mirror of
https://github.com/NixOS/nix
synced 2025-06-25 10:41:16 +02:00
Use transparent comparators for std::set<std::string> (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"})).
This commit is contained in:
parent
5278cd2396
commit
ebb836d499
12 changed files with 66 additions and 40 deletions
|
@ -25,11 +25,11 @@ namespace nix {
|
||||||
LengthPrefixedProtoHelper<CommonProto, T >::write(store, conn, t); \
|
LengthPrefixedProtoHelper<CommonProto, T >::write(store, conn, t); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define COMMA_ ,
|
||||||
COMMON_USE_LENGTH_PREFIX_SERIALISER(template<typename T>, std::vector<T>)
|
COMMON_USE_LENGTH_PREFIX_SERIALISER(template<typename T>, std::vector<T>)
|
||||||
COMMON_USE_LENGTH_PREFIX_SERIALISER(template<typename T>, std::set<T>)
|
COMMON_USE_LENGTH_PREFIX_SERIALISER(template<typename T COMMA_ typename Compare>, std::set<T COMMA_ Compare>)
|
||||||
COMMON_USE_LENGTH_PREFIX_SERIALISER(template<typename... Ts>, std::tuple<Ts...>)
|
COMMON_USE_LENGTH_PREFIX_SERIALISER(template<typename... Ts>, std::tuple<Ts...>)
|
||||||
|
|
||||||
#define COMMA_ ,
|
|
||||||
COMMON_USE_LENGTH_PREFIX_SERIALISER(
|
COMMON_USE_LENGTH_PREFIX_SERIALISER(
|
||||||
template<typename K COMMA_ typename V>,
|
template<typename K COMMA_ typename V>,
|
||||||
std::map<K COMMA_ V>)
|
std::map<K COMMA_ V>)
|
||||||
|
|
|
@ -72,14 +72,14 @@ DECLARE_COMMON_SERIALISER(DrvOutput);
|
||||||
template<>
|
template<>
|
||||||
DECLARE_COMMON_SERIALISER(Realisation);
|
DECLARE_COMMON_SERIALISER(Realisation);
|
||||||
|
|
||||||
|
#define COMMA_ ,
|
||||||
template<typename T>
|
template<typename T>
|
||||||
DECLARE_COMMON_SERIALISER(std::vector<T>);
|
DECLARE_COMMON_SERIALISER(std::vector<T>);
|
||||||
template<typename T>
|
template<typename T, typename Compare>
|
||||||
DECLARE_COMMON_SERIALISER(std::set<T>);
|
DECLARE_COMMON_SERIALISER(std::set<T COMMA_ Compare>);
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
DECLARE_COMMON_SERIALISER(std::tuple<Ts...>);
|
DECLARE_COMMON_SERIALISER(std::tuple<Ts...>);
|
||||||
|
|
||||||
#define COMMA_ ,
|
|
||||||
template<typename K, typename V>
|
template<typename K, typename V>
|
||||||
DECLARE_COMMON_SERIALISER(std::map<K COMMA_ V>);
|
DECLARE_COMMON_SERIALISER(std::map<K COMMA_ V>);
|
||||||
#undef COMMA_
|
#undef COMMA_
|
||||||
|
|
|
@ -343,7 +343,7 @@ struct Derivation : BasicDerivation
|
||||||
/**
|
/**
|
||||||
* inputs that are sub-derivations
|
* inputs that are sub-derivations
|
||||||
*/
|
*/
|
||||||
DerivedPathMap<std::set<OutputName>> inputDrvs;
|
DerivedPathMap<std::set<OutputName, std::less<>>> inputDrvs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print a derivation.
|
* Print a derivation.
|
||||||
|
|
|
@ -52,8 +52,10 @@ struct LengthPrefixedProtoHelper;
|
||||||
template<class Inner, typename T>
|
template<class Inner, typename T>
|
||||||
LENGTH_PREFIXED_PROTO_HELPER(Inner, std::vector<T>);
|
LENGTH_PREFIXED_PROTO_HELPER(Inner, std::vector<T>);
|
||||||
|
|
||||||
template<class Inner, typename T>
|
#define COMMA_ ,
|
||||||
LENGTH_PREFIXED_PROTO_HELPER(Inner, std::set<T>);
|
template<class Inner, typename T, typename Compare>
|
||||||
|
LENGTH_PREFIXED_PROTO_HELPER(Inner, std::set<T COMMA_ Compare>);
|
||||||
|
#undef COMMA_
|
||||||
|
|
||||||
template<class Inner, typename... Ts>
|
template<class Inner, typename... Ts>
|
||||||
LENGTH_PREFIXED_PROTO_HELPER(Inner, std::tuple<Ts...>);
|
LENGTH_PREFIXED_PROTO_HELPER(Inner, std::tuple<Ts...>);
|
||||||
|
@ -86,12 +88,11 @@ LengthPrefixedProtoHelper<Inner, std::vector<T>>::write(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Inner, typename T>
|
template<class Inner, typename T, typename Compare>
|
||||||
std::set<T>
|
std::set<T, Compare> LengthPrefixedProtoHelper<Inner, std::set<T, Compare>>::read(
|
||||||
LengthPrefixedProtoHelper<Inner, std::set<T>>::read(
|
|
||||||
const StoreDirConfig & store, typename Inner::ReadConn conn)
|
const StoreDirConfig & store, typename Inner::ReadConn conn)
|
||||||
{
|
{
|
||||||
std::set<T> resSet;
|
std::set<T, Compare> resSet;
|
||||||
auto size = readNum<size_t>(conn.from);
|
auto size = readNum<size_t>(conn.from);
|
||||||
while (size--) {
|
while (size--) {
|
||||||
resSet.insert(S<T>::read(store, conn));
|
resSet.insert(S<T>::read(store, conn));
|
||||||
|
@ -99,10 +100,9 @@ LengthPrefixedProtoHelper<Inner, std::set<T>>::read(
|
||||||
return resSet;
|
return resSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Inner, typename T>
|
template<class Inner, typename T, typename Compare>
|
||||||
void
|
void LengthPrefixedProtoHelper<Inner, std::set<T, Compare>>::write(
|
||||||
LengthPrefixedProtoHelper<Inner, std::set<T>>::write(
|
const StoreDirConfig & store, typename Inner::WriteConn conn, const std::set<T, Compare> & resSet)
|
||||||
const StoreDirConfig & store, typename Inner::WriteConn conn, const std::set<T> & resSet)
|
|
||||||
{
|
{
|
||||||
conn.to << resSet.size();
|
conn.to << resSet.size();
|
||||||
for (auto & key : resSet) {
|
for (auto & key : resSet) {
|
||||||
|
|
|
@ -27,20 +27,24 @@ struct OutputsSpec {
|
||||||
/**
|
/**
|
||||||
* A non-empty set of outputs, specified by name
|
* A non-empty set of outputs, specified by name
|
||||||
*/
|
*/
|
||||||
struct Names : std::set<OutputName> {
|
struct Names : std::set<OutputName, std::less<>> {
|
||||||
using std::set<OutputName>::set;
|
private:
|
||||||
|
using BaseType = std::set<OutputName, std::less<>>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using BaseType::BaseType;
|
||||||
|
|
||||||
/* These need to be "inherited manually" */
|
/* These need to be "inherited manually" */
|
||||||
|
|
||||||
Names(const std::set<OutputName> & s)
|
Names(const BaseType & s)
|
||||||
: std::set<OutputName>(s)
|
: BaseType(s)
|
||||||
{ assert(!empty()); }
|
{ assert(!empty()); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Needs to be "inherited manually"
|
* Needs to be "inherited manually"
|
||||||
*/
|
*/
|
||||||
Names(std::set<OutputName> && s)
|
Names(BaseType && s)
|
||||||
: std::set<OutputName>(s)
|
: BaseType(std::move(s))
|
||||||
{ assert(!empty()); }
|
{ assert(!empty()); }
|
||||||
|
|
||||||
/* This set should always be non-empty, so we delete this
|
/* This set should always be non-empty, so we delete this
|
||||||
|
|
|
@ -26,7 +26,9 @@ namespace nix {
|
||||||
}
|
}
|
||||||
|
|
||||||
SERVE_USE_LENGTH_PREFIX_SERIALISER(template<typename T>, std::vector<T>)
|
SERVE_USE_LENGTH_PREFIX_SERIALISER(template<typename T>, std::vector<T>)
|
||||||
SERVE_USE_LENGTH_PREFIX_SERIALISER(template<typename T>, std::set<T>)
|
#define COMMA_ ,
|
||||||
|
SERVE_USE_LENGTH_PREFIX_SERIALISER(template<typename T COMMA_ typename Compare>, std::set<T COMMA_ Compare>)
|
||||||
|
#undef COMMA_
|
||||||
SERVE_USE_LENGTH_PREFIX_SERIALISER(template<typename... Ts>, std::tuple<Ts...>)
|
SERVE_USE_LENGTH_PREFIX_SERIALISER(template<typename... Ts>, std::tuple<Ts...>)
|
||||||
|
|
||||||
#define SERVE_USE_LENGTH_PREFIX_SERIALISER_COMMA ,
|
#define SERVE_USE_LENGTH_PREFIX_SERIALISER_COMMA ,
|
||||||
|
|
|
@ -180,12 +180,12 @@ DECLARE_SERVE_SERIALISER(ServeProto::BuildOptions);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
DECLARE_SERVE_SERIALISER(std::vector<T>);
|
DECLARE_SERVE_SERIALISER(std::vector<T>);
|
||||||
template<typename T>
|
#define COMMA_ ,
|
||||||
DECLARE_SERVE_SERIALISER(std::set<T>);
|
template<typename T, typename Compare>
|
||||||
|
DECLARE_SERVE_SERIALISER(std::set<T COMMA_ Compare>);
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
DECLARE_SERVE_SERIALISER(std::tuple<Ts...>);
|
DECLARE_SERVE_SERIALISER(std::tuple<Ts...>);
|
||||||
|
|
||||||
#define COMMA_ ,
|
|
||||||
template<typename K, typename V>
|
template<typename K, typename V>
|
||||||
DECLARE_SERVE_SERIALISER(std::map<K COMMA_ V>);
|
DECLARE_SERVE_SERIALISER(std::map<K COMMA_ V>);
|
||||||
#undef COMMA_
|
#undef COMMA_
|
||||||
|
|
|
@ -26,7 +26,9 @@ namespace nix {
|
||||||
}
|
}
|
||||||
|
|
||||||
WORKER_USE_LENGTH_PREFIX_SERIALISER(template<typename T>, std::vector<T>)
|
WORKER_USE_LENGTH_PREFIX_SERIALISER(template<typename T>, std::vector<T>)
|
||||||
WORKER_USE_LENGTH_PREFIX_SERIALISER(template<typename T>, std::set<T>)
|
#define COMMA_ ,
|
||||||
|
WORKER_USE_LENGTH_PREFIX_SERIALISER(template<typename T COMMA_ typename Compare>, std::set<T COMMA_ Compare>)
|
||||||
|
#undef COMMA_
|
||||||
WORKER_USE_LENGTH_PREFIX_SERIALISER(template<typename... Ts>, std::tuple<Ts...>)
|
WORKER_USE_LENGTH_PREFIX_SERIALISER(template<typename... Ts>, std::tuple<Ts...>)
|
||||||
|
|
||||||
#define WORKER_USE_LENGTH_PREFIX_SERIALISER_COMMA ,
|
#define WORKER_USE_LENGTH_PREFIX_SERIALISER_COMMA ,
|
||||||
|
|
|
@ -135,7 +135,7 @@ struct WorkerProto
|
||||||
}
|
}
|
||||||
|
|
||||||
using Feature = std::string;
|
using Feature = std::string;
|
||||||
using FeatureSet = std::set<Feature>;
|
using FeatureSet = std::set<Feature, std::less<>>;
|
||||||
|
|
||||||
static const FeatureSet allFeatures;
|
static const FeatureSet allFeatures;
|
||||||
};
|
};
|
||||||
|
@ -273,12 +273,12 @@ DECLARE_WORKER_SERIALISER(WorkerProto::ClientHandshakeInfo);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
DECLARE_WORKER_SERIALISER(std::vector<T>);
|
DECLARE_WORKER_SERIALISER(std::vector<T>);
|
||||||
template<typename T>
|
#define COMMA_ ,
|
||||||
DECLARE_WORKER_SERIALISER(std::set<T>);
|
template<typename T, typename Compare>
|
||||||
|
DECLARE_WORKER_SERIALISER(std::set<T COMMA_ Compare>);
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
DECLARE_WORKER_SERIALISER(std::tuple<Ts...>);
|
DECLARE_WORKER_SERIALISER(std::tuple<Ts...>);
|
||||||
|
|
||||||
#define COMMA_ ,
|
|
||||||
template<typename K, typename V>
|
template<typename K, typename V>
|
||||||
DECLARE_WORKER_SERIALISER(std::map<K COMMA_ V>);
|
DECLARE_WORKER_SERIALISER(std::map<K COMMA_ V>);
|
||||||
#undef COMMA_
|
#undef COMMA_
|
||||||
|
|
|
@ -90,8 +90,8 @@ struct json_avoids_null<std::vector<T>> : std::true_type {};
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct json_avoids_null<std::list<T>> : std::true_type {};
|
struct json_avoids_null<std::list<T>> : std::true_type {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename Compare>
|
||||||
struct json_avoids_null<std::set<T>> : std::true_type {};
|
struct json_avoids_null<std::set<T, Compare>> : std::true_type {};
|
||||||
|
|
||||||
template<typename K, typename V>
|
template<typename K, typename V>
|
||||||
struct json_avoids_null<std::map<K, V>> : std::true_type {};
|
struct json_avoids_null<std::map<K, V>> : std::true_type {};
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename Compare>
|
||||||
std::vector<T> topoSort(std::set<T> items,
|
std::vector<T> topoSort(std::set<T, Compare> items,
|
||||||
std::function<std::set<T>(const T &)> getChildren,
|
std::function<std::set<T, Compare>(const T &)> getChildren,
|
||||||
std::function<Error(const T &, const T &)> makeCycleError)
|
std::function<Error(const T &, const T &)> makeCycleError)
|
||||||
{
|
{
|
||||||
std::vector<T> sorted;
|
std::vector<T> sorted;
|
||||||
std::set<T> visited, parents;
|
decltype(items) visited, parents;
|
||||||
|
|
||||||
std::function<void(const T & path, const T * parent)> dfsVisit;
|
std::function<void(const T & path, const T * parent)> dfsVisit;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ std::vector<T> topoSort(std::set<T> items,
|
||||||
if (!visited.insert(path).second) return;
|
if (!visited.insert(path).second) return;
|
||||||
parents.insert(path);
|
parents.insert(path);
|
||||||
|
|
||||||
std::set<T> references = getChildren(path);
|
auto references = getChildren(path);
|
||||||
|
|
||||||
for (auto & i : references)
|
for (auto & i : references)
|
||||||
/* Don't traverse into items that don't exist in our starting set. */
|
/* Don't traverse into items that don't exist in our starting set. */
|
||||||
|
|
|
@ -12,17 +12,35 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
typedef std::list<std::string> Strings;
|
typedef std::list<std::string> Strings;
|
||||||
typedef std::set<std::string> StringSet;
|
|
||||||
typedef std::map<std::string, std::string> StringMap;
|
typedef std::map<std::string, std::string> StringMap;
|
||||||
typedef std::map<std::string, std::string> StringPairs;
|
typedef std::map<std::string, std::string> StringPairs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias to ordered set container with transparent comparator.
|
||||||
|
*
|
||||||
|
* Used instead of std::set<std::string> 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<std::string, std::less<>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Paths are just strings.
|
* Paths are just strings.
|
||||||
*/
|
*/
|
||||||
typedef std::string Path;
|
typedef std::string Path;
|
||||||
typedef std::string_view PathView;
|
typedef std::string_view PathView;
|
||||||
typedef std::list<Path> Paths;
|
typedef std::list<Path> Paths;
|
||||||
typedef std::set<Path> PathSet;
|
|
||||||
|
/**
|
||||||
|
* Alias to an ordered set of `Path`s. Uses transparent comparator.
|
||||||
|
*
|
||||||
|
* @see StringSet
|
||||||
|
*/
|
||||||
|
using PathSet = std::set<Path, std::less<>>;
|
||||||
|
|
||||||
typedef std::vector<std::pair<std::string, std::string>> Headers;
|
typedef std::vector<std::pair<std::string, std::string>> Headers;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue