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