Skip to content

Commit bae6cef

Browse files
authored
lib.sources: small performance improvements (#536129)
2 parents 6c1529b + 14234b4 commit bae6cef

1 file changed

Lines changed: 74 additions & 46 deletions

File tree

lib/sources.nix

Lines changed: 74 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,31 @@
44
# Tested in lib/tests/sources.sh
55
let
66
inherit (lib.strings)
7+
escapeRegex
8+
hasPrefix
9+
hasSuffix
710
match
11+
removePrefix
12+
removeSuffix
813
split
14+
splitString
915
storeDir
10-
escapeRegex
11-
removePrefix
16+
stringLength
17+
substring
1218
;
1319
inherit (lib)
20+
any
1421
boolToString
15-
filter
16-
isString
17-
readFile
1822
concatStrings
19-
length
2023
elemAt
24+
fileContents
25+
filter
26+
head
2127
isList
22-
any
28+
isString
29+
last
30+
length
31+
readFile
2332
;
2433
inherit (lib.filesystem)
2534
pathIsRegularFile
@@ -41,6 +50,12 @@ let
4150
: 2\. Function argument
4251
*/
4352
cleanSourceFilter =
53+
let
54+
hasEmacsBackupFileSuffix = hasSuffix "~";
55+
hasObjectSuffix = hasSuffix ".o";
56+
hasSharedObjectSuffix = hasSuffix ".so";
57+
hasResultPrefix = hasPrefix "result";
58+
in
4459
name: type:
4560
let
4661
baseName = baseNameOf name;
@@ -62,17 +77,15 @@ let
6277
)
6378
||
6479
# Filter out editor backup / swap files.
65-
lib.hasSuffix "~" baseName
80+
hasEmacsBackupFileSuffix baseName
6681
|| match "^\\.sw[a-z]$" baseName != null
6782
|| match "^\\..*\\.sw[a-z]$" baseName != null
68-
||
69-
70-
# Filter out generates files.
71-
lib.hasSuffix ".o" baseName
72-
|| lib.hasSuffix ".so" baseName
83+
# Filter out generated files.
84+
|| hasObjectSuffix baseName
85+
|| hasSharedObjectSuffix baseName
7386
||
7487
# Filter out nix-build result symlinks
75-
(type == "symlink" && lib.hasPrefix "result" baseName)
88+
(type == "symlink" && hasResultPrefix baseName)
7689
||
7790
# Filter out sockets and other types of files we can't have in the store.
7891
(type == "unknown")
@@ -133,13 +146,13 @@ let
133146
{
134147
# A path or cleanSourceWith result to filter and/or rename.
135148
src,
136-
# Optional with default value: constant true (include everything)
149+
# Optional with default value of null (include everything)
137150
# The function will be combined with the && operator such
138151
# that src.filter is called lazily.
139152
# For implementing a filter, see
140153
# https://nixos.org/nix/manual/#builtin-filterSource
141154
# Type: A function (Path -> Type -> Bool)
142-
filter ? _path: _type: true,
155+
filter ? null,
143156
# Optional name to use as part of the store path.
144157
# This defaults to `src.name` or otherwise `"source"`.
145158
name ? null,
@@ -149,7 +162,13 @@ let
149162
in
150163
fromSourceAttributes {
151164
inherit (orig) origSrc;
152-
filter = path: type: filter path type && orig.filter path type;
165+
filter =
166+
if orig.filter == null then
167+
filter
168+
else if filter == null then
169+
orig.filter
170+
else
171+
path: type: filter path type && orig.filter path type;
153172
name = if name != null then name else orig.name;
154173
};
155174

@@ -178,11 +197,14 @@ let
178197
attrs
179198
// {
180199
filter =
181-
path: type:
182-
let
183-
r = attrs.filter path type;
184-
in
185-
builtins.trace "${attrs.name}.filter ${path} = ${boolToString r}" r;
200+
if attrs.filter == null then
201+
path: type: builtins.trace "${attrs.name}.filter ${path} = true" true
202+
else
203+
path: type:
204+
let
205+
r = attrs.filter path type;
206+
in
207+
builtins.trace "${attrs.name}.filter ${path} = ${boolToString r}" r;
186208
}
187209
)
188210
// {
@@ -218,13 +240,13 @@ let
218240
isFiltered = src ? _isLibCleanSourceWith;
219241
origSrc = if isFiltered then src.origSrc else src;
220242
in
221-
lib.cleanSourceWith {
243+
cleanSourceWith {
222244
filter = (
223245
path: type:
224246
let
225-
relPath = lib.removePrefix (toString origSrc + "/") (toString path);
247+
relPath = removePrefix (toString origSrc + "/") (toString path);
226248
in
227-
lib.any (re: match re relPath != null) regexes
249+
any (re: match re relPath != null) regexes
228250
);
229251
inherit src;
230252
};
@@ -272,7 +294,7 @@ let
272294
let
273295
base = baseNameOf name;
274296
in
275-
type == "directory" || lib.any (ext: lib.hasSuffix ext base) exts;
297+
type == "directory" || any (ext: hasSuffix ext base) exts;
276298
in
277299
cleanSourceWith { inherit filter src; };
278300

@@ -319,9 +341,9 @@ let
319341
packedRefsName = path + "/packed-refs";
320342
absolutePath =
321343
base: path:
322-
if lib.hasPrefix "/" path then
344+
if hasPrefix "/" path then
323345
path
324-
else if lib.hasPrefix "/" base then
346+
else if hasPrefix "/" base then
325347
"${base}/${path}"
326348
else
327349
"/${base}/${path}";
@@ -337,12 +359,12 @@ let
337359
{ error = "File contains no gitdir reference: " + path; }
338360
else
339361
let
340-
gitDir = absolutePath (dirOf path) (lib.head m);
362+
gitDir = absolutePath (dirOf path) (head m);
341363
commonDir'' =
342-
if pathIsRegularFile "${gitDir}/commondir" then lib.fileContents "${gitDir}/commondir" else gitDir;
343-
commonDir' = lib.removeSuffix "/" commonDir'';
364+
if pathIsRegularFile "${gitDir}/commondir" then fileContents "${gitDir}/commondir" else gitDir;
365+
commonDir' = removeSuffix "/" commonDir'';
344366
commonDir = absolutePath gitDir commonDir';
345-
refFile = lib.removePrefix "${commonDir}/" "${gitDir}/${file}";
367+
refFile = removePrefix "${commonDir}/" "${gitDir}/${file}";
346368
in
347369
readCommitFromFile refFile commonDir
348370

@@ -352,10 +374,10 @@ let
352374
# sometimes it stores something like: «ref: refs/heads/branch-name»
353375
then
354376
let
355-
fileContent = lib.fileContents fileName;
377+
fileContent = fileContents fileName;
356378
matchRef = match "^ref: (.*)$" fileContent;
357379
in
358-
if matchRef == null then { value = fileContent; } else readCommitFromFile (lib.head matchRef) path
380+
if matchRef == null then { value = fileContent; } else readCommitFromFile (head matchRef) path
359381

360382
else if
361383
pathIsRegularFile packedRefsName
@@ -373,14 +395,14 @@ let
373395
if refs == [ ] then
374396
{ error = "Could not find " + file + " in " + packedRefsName; }
375397
else
376-
{ value = lib.head (matchRef (lib.head refs)); }
398+
{ value = head (matchRef (head refs)); }
377399

378400
else
379401
{ error = "Not a .git directory: " + toString path; };
380402
in
381403
readCommitFromFile "HEAD";
382404

383-
pathHasContext = builtins.hasContext or (lib.hasPrefix storeDir);
405+
pathHasContext = builtins.hasContext or (hasPrefix storeDir);
384406

385407
canCleanSource = src: src ? _isLibCleanSourceWith || !(pathHasContext (toString src));
386408

@@ -403,24 +425,31 @@ let
403425
{
404426
# The original path
405427
origSrc = if isFiltered then src.origSrc else src;
406-
filter = if isFiltered then src.filter else _: _: true;
428+
filter = if isFiltered then src.filter else null; # make sure to handle this!
407429
name = if isFiltered then src.name else "source";
408430
};
409431

410432
# fromSourceAttributes : SourceAttrs -> Source
411433
#
412434
# Inverse of toSourceAttributes for Source objects.
413435
fromSourceAttributes =
436+
let
437+
inherit (builtins) path;
438+
in
414439
{
415440
origSrc,
416441
filter,
417442
name,
418443
}:
419444
{
420445
_isLibCleanSourceWith = true;
421-
inherit origSrc filter name;
422-
outPath = builtins.path {
423-
inherit filter name;
446+
inherit origSrc name;
447+
# preserve outside checks, since a filter of null looks odd for
448+
# comparisons
449+
filter = if filter == null then _: _: true else filter;
450+
outPath = path {
451+
inherit name;
452+
${if filter != null then "filter" else null} = filter;
424453
path = origSrc;
425454
};
426455
};
@@ -431,15 +460,14 @@ let
431460
urlToName =
432461
url:
433462
let
434-
inherit (lib.strings) stringLength;
435-
base = baseNameOf (lib.removeSuffix "/" (lib.last (lib.splitString ":" (toString url))));
463+
base = baseNameOf (removeSuffix "/" (last (splitString ":" (toString url))));
436464
# chop away one git or archive-related extension
437465
removeExt =
438466
name:
439467
let
440468
matchExt = match "(.*)\\.(git|tar|zip|gz|tgz|bz|tbz|bz2|tbz2|lzma|txz|xz|zstd)$" name;
441469
in
442-
if matchExt != null then lib.head matchExt else name;
470+
if matchExt != null then head matchExt else name;
443471
# apply function f to string x while the result shrinks
444472
shrink =
445473
f: x:
@@ -461,9 +489,9 @@ let
461489
matchVer = match "([A-Za-z]+[-_. ]?)*(v)?([0-9.]+.*)" baseRev;
462490
in
463491
if matchHash != null then
464-
builtins.substring 0 7 baseRev
492+
substring 0 7 baseRev
465493
else if matchVer != null then
466-
lib.last matchVer
494+
last matchVer
467495
else
468496
baseRev;
469497

@@ -623,7 +651,7 @@ let
623651

624652
in
625653
src: patterns:
626-
lib.cleanSourceWith {
654+
cleanSourceWith {
627655
filter = mkSourceFilter src patterns;
628656
inherit src;
629657
};

0 commit comments

Comments
 (0)