diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2005-09-19 09:49:52 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2005-09-19 09:49:52 +0000 |
commit | 479b2d4168c079f6fe8738591f67e16c0ac0fed5 (patch) | |
tree | b7362cb2d9865be83799cd57faffdc46a5b3362f | |
parent | f0aa2121dae808cd866e70cf2ef48384ac18174f (diff) |
make package opening more efficient (and maybe more intuitive) by
delaying reading the full info directory to a temporary directory.
When we open a package, we just scan for the CONTENTS. If it's the
first file, we stash it into memory and STOP there, delaying grabbing
the rest of the special files to the first call to info().
Make sure the next() proxy shows only real file, by grabbing info files
if necessary.
Introduce handle->plist() method that can retrieve the plist from either
the version stored in memory, or in a file in the temp directory.
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/PackageLocator.pm | 131 |
1 files changed, 76 insertions, 55 deletions
diff --git a/usr.sbin/pkg_add/OpenBSD/PackageLocator.pm b/usr.sbin/pkg_add/OpenBSD/PackageLocator.pm index bd253c55e22..49f41a853ef 100644 --- a/usr.sbin/pkg_add/OpenBSD/PackageLocator.pm +++ b/usr.sbin/pkg_add/OpenBSD/PackageLocator.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: PackageLocator.pm,v 1.38 2005/09/17 12:45:49 espie Exp $ +# $OpenBSD: PackageLocator.pm,v 1.39 2005/09/19 09:49:51 espie Exp $ # # Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org> # @@ -54,10 +54,13 @@ sub wipe_info my ($self, $pkg) = @_; require File::Path; - my $dir = $pkg->info(); - File::Path::rmtree($dir); - delete $pkg->{dir}; + my $dir = $pkg->{dir}; + if (defined $dir) { + + File::Path::rmtree($dir); + delete $pkg->{dir}; + } } # by default, all objects may exist @@ -563,21 +566,15 @@ sub openArchive sub grabInfoFiles { my $self = shift; - my $dir = $self->{dir}; - - if (defined $self->{plist}) { - require OpenBSD::PackingList; + my $dir = $self->{dir} = OpenBSD::Temp::dir(); - $self->{plist}->tofile($dir.CONTENTS); - delete $self->{plist}; - } elsif (defined $self->{contents}) { + if (defined $self->{contents} && ! -f $dir.CONTENTS) { open my $fh, '>', $dir.CONTENTS or die "Permission denied"; print $fh $self->{contents}; close $fh; - delete $self->{contents}; } - while (my $e = $self->next()) { + while (my $e = $self->intNext()) { if ($e->isFile() && is_info_name($e->{name})) { $e->{name}=$dir.$e->{name}; eval { $e->create(); }; @@ -595,44 +592,46 @@ sub grabInfoFiles return 1; } -sub grabPlist +sub scanPackage { - my ($self, $pkgname, $arch, $code) = @_; - if (!$self->openArchive()) { - return undef; - } - - while (my $e = $self->next()) { - if ($e->{name} ne CONTENTS) { - if ($e->{name} =~ m/\/\+CONTENTS$/) { - $self->{prefix} = $'; - bless $self, "OpenBSD:FatPackageLocation"; - } else { + my $self = shift; + while (my $e = $self->intNext()) { + if ($e->isFile() && is_info_name($e->{name})) { + if ($e->{name} eq CONTENTS && !defined $self->{dir}) { + $self->{contents} = $e->contents(); last; } - } - my $value = $e->contents(); - open my $fh, '<', \$value or next; - require OpenBSD::PackingList; - $pkgname =~ s/\.tgz$//; - my $plist = OpenBSD::PackingList->read($fh, $code); - close $fh; - next if defined $pkgname and $plist->pkgname() ne $pkgname; - if ($plist->has('arch')) { - if ($plist->{arch}->check($arch)) { - if (!defined $code) { - $self->{plist} = $plist; - } else { - $self->{contents} = $value; - } - return $plist; + if (!defined $self->{dir}) { + $self->{dir} = OpenBSD::Temp::dir(); } + $e->{name}=$self->{dir}.$e->{name}; + eval { $e->create(); }; + if ($@) { + unlink($e->{name}); + $@ =~ s/\s+at.*//; + print STDERR $@; + return 0; + } + } else { + $self->unput(); + last; } } - # hopeless - $self->close(); + return 1; +} - return undef; +sub grabPlist +{ + my ($self, $pkgname, $arch, $code) = @_; + + my $pkg = $self->openPackage($pkgname, $arch); + if (defined $pkg) { + my $plist = $self->plist($code); + $pkg->wipe_info(); + return $plist; + } else { + return undef; + } } sub openPackage @@ -641,32 +640,31 @@ sub openPackage if (!$self->openArchive()) { return undef; } - my $dir = OpenBSD::Temp::dir(); - $self->{dir} = $dir; + $self->scanPackage(); - $self->grabInfoFiles(); - - if (-f $dir.CONTENTS) { + if (defined $self->{contents}) { return $self; } # maybe it's a fat package. - while (my $e = $self->next()) { + while (my $e = $self->intNext()) { unless ($e->{name} =~ m/\/\+CONTENTS$/) { last; } my $prefix = $`; - $e->{name}=$dir.CONTENTS; - eval { $e->create(); }; + my $contents = $e->contents(); require OpenBSD::PackingList; + $pkgname =~ s/\.tgz$//; - my $plist = OpenBSD::PackingList->fromfile($dir.CONTENTS, \&OpenBSD::PackingList::FatOnly); + + my $plist = OpenBSD::PackingList->fromfile(\$contents, + \&OpenBSD::PackingList::FatOnly); next if defined $pkgname and $plist->pkgname() ne $pkgname; if ($plist->has('arch')) { if ($plist->{arch}->check($arch)) { $self->{filter} = $prefix; bless $self, "OpenBSD::FatPackageLocation"; - $self->grabInfoFiles(); + $self->{contents} = $contents; return $self; } } @@ -686,6 +684,9 @@ sub wipe_info sub info { my $self = shift; + if (!defined $self->{dir}) { + $self->grabInfoFiles(); + } return $self->{dir}; } @@ -695,7 +696,17 @@ sub plist require OpenBSD::PackingList; - return OpenBSD::PackingList->fromfile($self->info().CONTENTS, $code); + if (defined $self->{contents}) { + my $value = $self->{contents}; + return OpenBSD::PackingList->fromfile(\$value, $code); + } elsif (defined $self->{dir} && -f $self->{dir}.CONTENTS) { + return OpenBSD::PackingList->fromfile($self->{dir}.CONTENTS, + $code); + } + # hopeless + $self->close(); + + return undef; } sub close @@ -731,6 +742,16 @@ sub next { my $self = shift; + if (!defined $self->{dir}) { + $self->grabInfoFiles(); + } + return $self->intNext(); +} + +sub intNext +{ + my $self = shift; + if (!defined $self->{fh}) { if (!$self->reopen()) { return undef; |