summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2005-09-19 09:49:52 +0000
committerMarc Espie <espie@cvs.openbsd.org>2005-09-19 09:49:52 +0000
commit479b2d4168c079f6fe8738591f67e16c0ac0fed5 (patch)
treeb7362cb2d9865be83799cd57faffdc46a5b3362f
parentf0aa2121dae808cd866e70cf2ef48384ac18174f (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.pm131
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;