diff options
author | Silvan Mosberger <contact@infinisil.com> | 2023-11-26 23:28:39 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-26 23:28:39 +0100 |
commit | 627af21e87ce5d6a456f485292ac4ac2bc1f469f (patch) | |
tree | 33ada414becfcdea9f0526ffc1551cec4a665484 /lib | |
parent | 64b86e474114f7c6135fbb58fd4753595a0b1510 (diff) | |
parent | 4b4d4138177fd467cd8e726470824afac6ad3df5 (diff) |
Merge pull request #269637 from adisbladis/lib-meta-avoid-alloc-platformmatch
lib.meta: Avoid attrset allocation in platformMatch
Diffstat (limited to 'lib')
-rw-r--r-- | lib/meta.nix | 32 | ||||
-rw-r--r-- | lib/tests/misc.nix | 20 |
2 files changed, 42 insertions, 10 deletions
diff --git a/lib/meta.nix b/lib/meta.nix index 2e817c42327d6..1a43016d27c44 100644 --- a/lib/meta.nix +++ b/lib/meta.nix @@ -3,6 +3,11 @@ { lib }: +let + inherit (lib) matchAttrs any all; + inherit (builtins) isString; + +in rec { @@ -83,14 +88,21 @@ rec { We can inject these into a pattern for the whole of a structured platform, and then match that. */ - platformMatch = platform: elem: let - pattern = - if builtins.isString elem - then { system = elem; } - else if elem?parsed - then elem - else { parsed = elem; }; - in lib.matchAttrs pattern platform; + platformMatch = platform: elem: ( + # Check with simple string comparison if elem was a string. + # + # The majority of comparisons done with this function will be against meta.platforms + # which contains a simple platform string. + # + # Avoiding an attrset allocation results in significant performance gains (~2-30) across the board in OfBorg + # because this is a hot path for nixpkgs. + if isString elem then platform ? system && elem == platform.system + else matchAttrs ( + # Normalize platform attrset. + if elem ? parsed then elem + else { parsed = elem; } + ) platform + ); /* Check if a package is available on a given platform. @@ -102,8 +114,8 @@ rec { 2. None of `meta.badPlatforms` pattern matches the given platform. */ availableOn = platform: pkg: - ((!pkg?meta.platforms) || lib.any (platformMatch platform) pkg.meta.platforms) && - lib.all (elem: !platformMatch platform elem) (pkg.meta.badPlatforms or []); + ((!pkg?meta.platforms) || any (platformMatch platform) pkg.meta.platforms) && + all (elem: !platformMatch platform elem) (pkg.meta.badPlatforms or []); /* Get the corresponding attribute in lib.licenses from the SPDX ID. diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 06cb5e763e2c2..8f4a37149d92c 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -1948,4 +1948,24 @@ runTests { testGetExe'FailureSecondArg = testingThrow ( getExe' { type = "derivation"; } "dir/executable" ); + + testPlatformMatch = { + expr = meta.platformMatch { system = "x86_64-linux"; } "x86_64-linux"; + expected = true; + }; + + testPlatformMatchAttrs = { + expr = meta.platformMatch (systems.elaborate "x86_64-linux") (systems.elaborate "x86_64-linux").parsed; + expected = true; + }; + + testPlatformMatchNoMatch = { + expr = meta.platformMatch { system = "x86_64-darwin"; } "x86_64-linux"; + expected = false; + }; + + testPlatformMatchMissingSystem = { + expr = meta.platformMatch { } "x86_64-linux"; + expected = false; + }; } |