diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2009-12-30 19:04:07 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2009-12-30 19:04:07 +0000 |
commit | 491effe1596800d81e178bc174c6b8350536ea90 (patch) | |
tree | d16d4f1a7490a98f88531acbda443f599b2739d1 /usr.sbin | |
parent | 41c0576c65ec06b1a15013b6ad78b5e8b7e3f62c (diff) |
more changes and optimizations: create unique dewey objects, so I can
compare them directly and avoid storing the string.
on typical use through a large update, 2/3 cache hits.
also, remove switch on <,> by writing subclasses. Actually makes things
clearer.
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/PackageName.pm | 223 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/PkgSpec.pm | 4 |
2 files changed, 154 insertions, 73 deletions
diff --git a/usr.sbin/pkg_add/OpenBSD/PackageName.pm b/usr.sbin/pkg_add/OpenBSD/PackageName.pm index d9c5ea8554c..02375f6f8fa 100644 --- a/usr.sbin/pkg_add/OpenBSD/PackageName.pm +++ b/usr.sbin/pkg_add/OpenBSD/PackageName.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: PackageName.pm,v 1.37 2009/12/30 16:43:08 espie Exp $ +# $OpenBSD: PackageName.pm,v 1.38 2009/12/30 19:04:06 espie Exp $ # # Copyright (c) 2003-2007 Marc Espie <espie@openbsd.org> # @@ -46,6 +46,8 @@ sub splitname my $cached = {}; my $calls = 0; my $nohits = 0; +my $dewey_calls = 0; +my $dewey_hits = 0; my $tocalls = 0; my $strings = 0; @@ -56,9 +58,11 @@ sub stats print STDERR "Size=", Devel::Size::total_size($cached), "\n"; print STDERR "Total calls: ", $calls, "\n"; print STDERR "Cache hits: ", $calls - $nohits, "\n"; + print STDERR "Dewey calls: ", $dewey_calls, "\n"; + print STDERR "Dewey hits: ", $dewey_hits, "\n"; print STDERR "to_string calls: ", $tocalls, "\n"; print STDERR "string compares: ", $strings, "\n"; - print STDERR join(',', sort keys %$cached), "\n"; +# print STDERR join(',', sort keys %$cached), "\n"; } sub from_string @@ -66,10 +70,11 @@ sub from_string my ($class, $_) = @_; $calls++; if (!defined $cached->{$_}) { - $cached->{$_} = $class->new_from_string($_); $nohits++; + return $cached->{$_} = $class->new_from_string($_); + } else { + return $cached->{$_}; } - return $cached->{$_}; } sub new_from_string @@ -170,84 +175,50 @@ sub find_partial return @result; } -package OpenBSD::PackageName::version; +package OpenBSD::PackageName::dewey; + +my $cache = {}; -sub make_dewey +sub from_string { - my $o = shift; - $o->{deweys} = [ split(/\./o, $o->{string}) ]; + my ($class, $string) = @_; + my $o = bless { deweys => [ split(/\./o, $string) ]}, $class; for my $suffix (qw(rc beta pre pl)) { if ($o->{deweys}->[-1] =~ m/^(\d+)$suffix(\d*)$/) { $o->{deweys}->[-1] = $1; $o->{$suffix} = $2; } } + return $o; } -sub p -{ - my $self = shift; - - return defined $self->{p} ? $self->{p} : -1; -} - -sub v -{ - my $self = shift; - - return defined $self->{v} ? $self->{v} : -1; -} - -sub from_string +sub make { my ($class, $string) = @_; - my $o = bless {}, $class; - if ($string =~ m/^(.*)v(\d+)$/o) { - $o->{v} = $2; - $string = $1; - } - if ($string =~ m/^(.*)p(\d+)$/o) { - $o->{p} = $2; - $string = $1; + $dewey_calls++; + if (!defined $cache->{$string}) { + return $cache->{$string} = $class->from_string($string); + } else { + $dewey_hits++; + return $cache->{$string}; } - $o->{string} = $string; - - $o->make_dewey; - return $o; } sub to_string { - my $o = shift; - $tocalls++; - my $string = $o->{string}; - if (defined $o->{p}) { - $string .= 'p'.$o->{p}; - } - if (defined $o->{v}) { - $string .= 'v'.$o->{v}; + my $self = shift; + my $r = join('.', [$self->{deweys}]); + for my $suffix (qw(pl pre beta rc)) { + if (defined $self->{$suffix}) { + $r .= $suffix . $self->{$suffix}; + } } - return $string; -} - -sub pnum_compare -{ - my ($a, $b) = @_; - return $a->p <=> $b->p; + return $r; } sub compare { my ($a, $b) = @_; - # Simple case: epoch number - if ($a->v != $b->v) { - return $a->v <=> $b->v; - } - # Simple case: only p number differs - if ($a->{string} eq $b->{string}) { - $strings++; - return $a->pnum_compare($b); - } # Try a diff in dewey numbers first for (my $i = 0; ; $i++) { if (!defined $a->{deweys}->[$i]) { @@ -301,9 +272,86 @@ sub dewey_compare return $a cmp $b; } +package OpenBSD::PackageName::version; + +sub p +{ + my $self = shift; + + return defined $self->{p} ? $self->{p} : -1; +} + +sub v +{ + my $self = shift; + + return defined $self->{v} ? $self->{v} : -1; +} + +sub from_string +{ + my ($class, $string) = @_; + my $o = bless {}, $class; + if ($string =~ m/^(.*)v(\d+)$/o) { + $o->{v} = $2; + $string = $1; + } + if ($string =~ m/^(.*)p(\d+)$/o) { + $o->{p} = $2; + $string = $1; + } + $o->{dewey} = OpenBSD::PackageName::dewey->make($string); + + return $o; +} + +sub to_string +{ + my $o = shift; + $tocalls++; + my $string = $o->{dewey}->to_string; + if (defined $o->{p}) { + $string .= 'p'.$o->{p}; + } + if (defined $o->{v}) { + $string .= 'v'.$o->{v}; + } + return $string; +} + +sub pnum_compare +{ + my ($a, $b) = @_; + return $a->p <=> $b->p; +} + +sub compare +{ + my ($a, $b) = @_; + # Simple case: epoch number + if ($a->v != $b->v) { + return $a->v <=> $b->v; + } + # Simple case: only p number differs + if ($a->{dewey} eq $b->{dewey}) { + $strings++; + return $a->pnum_compare($b); + } + + return $a->{dewey}->compare($b->{dewey}); +} + package OpenBSD::PackageName::versionspec; our @ISA = qw(OpenBSD::PackageName::version); +my $ops = { + '<' => 'lt', + '<=' => 'le', + '>' => 'gt', + '>=' => 'ge', + '=' => 'eq' +}; + sub from_string { my ($class, $s) = @_; @@ -311,9 +359,8 @@ sub from_string if ($s =~ m/^(\>\=|\>|\<\=|\<|\=)(.*)$/) { ($op, $version) = ($1, $2); } - my $self = $class->SUPER::from_string($version); - $self->{op} = $op; - return $self; + bless $class->SUPER::from_string($version), + "OpenBSD::PackageName::version::$ops->{$op}"; } sub pnum_compare @@ -326,18 +373,52 @@ sub pnum_compare } } +sub is_exact +{ + return 0; +} +package OpenBSD::PackageName::version::lt; +our @ISA = qw(OpenBSD::PackageName::versionspec); sub match { my ($self, $b) = @_; - - my $op = $self->{op}; - - my $compare = - $self->compare($b); - return 0 if $op eq '<' && $compare >= 0; - return 0 if $op eq '<=' && $compare > 0; - return 0 if $op eq '>' && $compare <= 0; - return 0 if $op eq '>=' && $compare < 0; - return 0 if $op eq '=' && $compare != 0; + -$self->compare($b) >= 0 ? 0 : 1; +} + +package OpenBSD::PackageName::version::le; +our @ISA = qw(OpenBSD::PackageName::versionspec); +sub match +{ + my ($self, $b) = @_; + -$self->compare($b) <= 0 ? 1 : 0; +} + +package OpenBSD::PackageName::version::gt; +our @ISA = qw(OpenBSD::PackageName::versionspec); +sub match +{ + my ($self, $b) = @_; + -$self->compare($b) > 0 ? 1 : 0; +} + +package OpenBSD::PackageName::version::ge; +our @ISA = qw(OpenBSD::PackageName::versionspec); +sub match +{ + my ($self, $b) = @_; + -$self->compare($b) >= 0 ? 1 : 0; +} + +package OpenBSD::PackageName::version::eq; +our @ISA = qw(OpenBSD::PackageName::versionspec); +sub match +{ + my ($self, $b) = @_; + -$self->compare($b) == 0 ? 1 : 0; +} + +sub is_exact +{ return 1; } diff --git a/usr.sbin/pkg_add/OpenBSD/PkgSpec.pm b/usr.sbin/pkg_add/OpenBSD/PkgSpec.pm index a2e820f5cd5..0862d0ec617 100644 --- a/usr.sbin/pkg_add/OpenBSD/PkgSpec.pm +++ b/usr.sbin/pkg_add/OpenBSD/PkgSpec.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: PkgSpec.pm,v 1.24 2009/12/30 16:43:08 espie Exp $ +# $OpenBSD: PkgSpec.pm,v 1.25 2009/12/30 19:04:06 espie Exp $ # # Copyright (c) 2003-2007 Marc Espie <espie@openbsd.org> # @@ -283,7 +283,7 @@ sub add_version_constraints my ($class, $constraints, $vspec) = @_; return if $vspec eq '*'; # XXX my $v = OpenBSD::PkgSpec::versionspec->new($vspec); - die "not a good exact spec" if $$v->{op} ne '='; + die "not a good exact spec" if !$$v->is_exact; delete $$v->{p}; push(@$constraints, $v); } |