Skip to content

Commit

Permalink
Streamline CURI.candidates
Browse files Browse the repository at this point in the history
- don't use returns, let the failed if return Empty
- only create Pairs for entries that actually match, rather than
  creating a Pair with a meta hash for each entry, and then grepping
  on the matchers firing
- don't use samewith in the slow path candidate

This also removes support for level 0 repositories.  The chance
that there is still an un-updated repo from before January 2016
in production, is deemed to low to warrant keeping supporting it.
  • Loading branch information
lizmat committed Apr 6, 2022
1 parent 1afc3f4 commit 32b7d33
Showing 1 changed file with 54 additions and 59 deletions.
113 changes: 54 additions & 59 deletions src/core.c/CompUnit/Repository/Installation.pm6
Expand Up @@ -463,70 +463,65 @@ sub MAIN(:$name, :$auth, :$ver, *@, *%) {

proto method candidates(|) {*}
multi method candidates(Str:D $name, :$auth, :$ver, :$api) {
return samewith(CompUnit::DependencySpecification.new(
self.candidates:
CompUnit::DependencySpecification.new:
short-name => $name,
auth-matcher => $auth,
version-matcher => $ver,
api-matcher => $api,
));
}
multi method candidates(CompUnit::DependencySpecification $spec) {
return Empty unless $spec.from eq 'Perl6';

# $lookup is a file system resource that acts as a fast meta data lookup for a given module short name.
my $lookup = self!short-dir.add(nqp::sha1($spec.short-name));
return Empty unless $lookup.e;

# Each item contains a subset of meta data - notably items needed `use "Foo:ver<*>"`
# All items match the given module short name, but may differ in ver, auth, api, etc.
my $metas := (
self!repository-version < 1
?? $lookup.lines.unique.map({
$_ => self!read-dist($_)
})
!! $lookup.dir.map({
my ($ver, $auth, $api, $source, $checksum) = $_.slurp.split("\n");
$_.basename => {
auth => $auth,
api => Version.new( $api || 0 ), # Create the Version objects once
ver => Version.new( $ver || 0 ), # (used to compare, and then sort)
source => $source || Any,
checksum => $checksum || Str,
}
multi method candidates(CompUnit::DependencySpecification:D $spec) {
if $spec.from eq 'Perl6'
# $lookup is a file system resource that acts as a fast meta data
# lookup for a given module short name.
&& (my $lookup = self!short-dir.add(nqp::sha1($spec.short-name))).e {

my $auth-matcher := $spec.auth-matcher;
my $version-matcher := $spec.version-matcher;
my $api-matcher := $spec.api-matcher;

# Each item contains a subset of meta data - notably items needed
# `use "Foo:ver<*>"`. All items match the given module short name,
$lookup.dir.map(-> $entry {
my ($ver,$auth,$api,$source,$checksum) = $entry.slurp.lines;
if ($ver := Version.new($ver || 0)) ~~ $version-matcher {
if $auth ~~ $auth-matcher {
if ($api := Version.new($api || 0)) ~~ $api-matcher {
Pair.new:
$entry.basename,
Map.new((
:$ver,
:$auth,
:$api,
:source($source || Any),
:checksum($checksum || Str),
))
}
})
);

my $auth-matcher := $spec.auth-matcher;
my $version-matcher := $spec.version-matcher;
my $api-matcher := $spec.api-matcher;

# $metas has already been filtered by name via $lookup, so do
# remaining filtering on fast lookup fields
$metas.grep({
my %meta := .value;
%meta<auth> ~~ $auth-matcher
and %meta<ver> ~~ $version-matcher
and %meta<api> ~~ $api-matcher
})

# Sort from highest to lowest by version and api
.sort(*.value<ver>)
.sort(*.value<api>)
.reverse

# There is nothing left to do with the subset of meta data, so
# initialize a lazy distribution with it
.map({
LazyDistribution.new:
:dist-id(.key),
:meta(.value),
:read-dist(-> $dist { self!read-dist($dist) }),
:$.prefix
})

# A different policy might wish to implement additional/alternative filtering or sorting at this point,
# with the caveat that calling a non-lazy field will require parsing json for each matching distribution.
# .grep({.meta<license> eq 'Artistic-2.0'}).sort(-*.meta<production>)`
}
}
})

# Sort from highest to lowest by version and api
.sort(*.value<ver>)
.sort(*.value<api>)
.reverse

# There is nothing left to do with the subset of meta data, so
# initialize a lazy distribution with it
.map({
LazyDistribution.new:
:dist-id(.key),
:meta(.value),
:read-dist(-> $dist { self!read-dist($dist) }),
:$.prefix
})

# A different policy might wish to implement additional/alternative
# filtering or sorting at this point, with the caveat that calling
# a non-lazy field will require parsing json for each matching
# distribution.
# .grep({.meta<license> eq 'Artistic-2.0'}).sort(-*.meta<production>)`
}
}

# An equivalent of self.candidates($spec).head that caches the best match
Expand Down

0 comments on commit 32b7d33

Please sign in to comment.