Merge pull request #152392 from polykernel/attrset-optimizations-patch-1

lib/attrset: various function optimizations
This commit is contained in:
pennae 2022-01-11 16:01:52 +00:00 committed by GitHub
commit 6d44bc5b90
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -3,9 +3,9 @@
let
inherit (builtins) head tail length;
inherit (lib.trivial) and;
inherit (lib.trivial) id;
inherit (lib.strings) concatStringsSep sanitizeDerivationName;
inherit (lib.lists) foldr foldl' concatMap concatLists elemAt;
inherit (lib.lists) foldr foldl' concatMap concatLists elemAt all;
in
rec {
@ -73,9 +73,9 @@ rec {
getAttrFromPath ["z" "z"] x
=> error: cannot find attribute `z.z'
*/
getAttrFromPath = attrPath: set:
getAttrFromPath = attrPath:
let errorMsg = "cannot find attribute `" + concatStringsSep "." attrPath + "'";
in attrByPath attrPath (abort errorMsg) set;
in attrByPath attrPath (abort errorMsg);
/* Return the specified attributes from a set.
@ -154,12 +154,12 @@ rec {
foldAttrs (n: a: [n] ++ a) [] [{ a = 2; } { a = 3; }]
=> { a = [ 2 3 ]; }
*/
foldAttrs = op: nul: list_of_attrs:
foldAttrs = op: nul:
foldr (n: a:
foldr (name: o:
o // { ${name} = op n.${name} (a.${name} or nul); }
) a (attrNames n)
) {} list_of_attrs;
) {};
/* Recursively collect sets that verify a given predicate named `pred'
@ -295,14 +295,14 @@ rec {
*/
mapAttrsRecursiveCond = cond: f: set:
let
recurse = path: set:
recurse = path:
let
g =
name: value:
if isAttrs value && cond value
then recurse (path ++ [name]) value
else f (path ++ [name]) value;
in mapAttrs g set;
in mapAttrs g;
in recurse [] set;
@ -369,7 +369,7 @@ rec {
value = f name (catAttrs name sets);
}) names);
/* Implementation note: Common names appear multiple times in the list of
/* Implementation note: Common names appear multiple times in the list of
names, hopefully this does not affect the system because the maximal
laziness avoid computing twice the same expression and listToAttrs does
not care about duplicated attribute names.
@ -420,8 +420,8 @@ rec {
let f = attrPath:
zipAttrsWith (n: values:
let here = attrPath ++ [n]; in
if tail values == []
|| pred here (head (tail values)) (head values) then
if length values == 1
|| pred here (elemAt values 1) (head values) then
head values
else
f here values
@ -447,10 +447,7 @@ rec {
}
*/
recursiveUpdate = lhs: rhs:
recursiveUpdateUntil (path: lhs: rhs:
!(isAttrs lhs && isAttrs rhs)
) lhs rhs;
recursiveUpdate = recursiveUpdateUntil (path: lhs: rhs: !(isAttrs lhs && isAttrs rhs));
/* Returns true if the pattern is contained in the set. False otherwise.
@ -459,8 +456,8 @@ rec {
=> true
*/
matchAttrs = pattern: attrs: assert isAttrs pattern;
foldr and true (attrValues (zipAttrsWithNames (attrNames pattern) (n: values:
let pat = head values; val = head (tail values); in
all id (attrValues (zipAttrsWithNames (attrNames pattern) (n: values:
let pat = head values; val = elemAt values 1; in
if length values == 1 then false
else if isAttrs pat then isAttrs val && matchAttrs pat val
else pat == val