DarkPAN-Indexer
view release on metacpan or search on metacpan
lib/DarkPAN/Indexer.pm view on Meta::CPAN
# .gz suffix drives compression in retrieve_index/publish_index.
########################################################################
sub _index_key {
########################################################################
my ($self) = @_;
my $key = $self->get_config->{packages_version_index};
croak "ERROR: packages_version_index not set in config\n"
if !defined $key || $key eq q{};
return $key;
}
########################################################################
# create_index: build a fresh index from every distribution in storage.
# list_distributions -> format->create_index(fh) -> load_index(create)
# -> publish_index. Full rebuild; authoritative.
########################################################################
sub create_index {
########################################################################
my ($self) = @_;
my $storage = $self->get_storage;
my $format = $self->get_format;
my $index = $self->_index_key;
my $guard = $storage->lock($index)
or croak "ERROR: could not acquire lock on $index\n";
# format writes the neutral TSV interchange for all distributions...
my ( $tsv_fh, $tsv_file ) = File::Temp::tempfile( DIR => '/tmp', UNLINK => 1 );
my $stats = $format->create_index(
output => $tsv_fh,
distributions => [ $storage->list_distributions ],
fetch => sub { $self->_fetch_dist_to_tmp( $_[0] ) }
);
close $tsv_fh;
# ...then loads that interchange into a fresh database, which we publish.
my ( undef, $db_file ) = File::Temp::tempfile( DIR => '/tmp', UNLINK => 1, SUFFIX => '.db' );
$format->load_index(
input => $tsv_file,
database => $db_file,
create => $TRUE,
);
$storage->publish_index( $db_file, $index );
return $stats;
}
########################################################################
# update_index: incrementally re-index ONE distribution.
# retrieve current index -> open it -> format->update_index(that dist)
# -> publish. Locked for the whole read-modify-write.
########################################################################
sub update_index {
########################################################################
my ( $self, %args ) = @_;
my $distribution = $args{distribution}
or croak "ERROR: update_index requires a distribution\n";
my $storage = $self->get_storage;
my $format = $self->get_format;
my $index = $self->_index_key;
my $guard = $storage->lock($index)
or croak "ERROR: could not acquire lock on $index\n";
# bring the current index down to a local, writable db file
my $db_file = $storage->retrieve_index( $index, '.db' );
# delete-then-insert for this distribution happens inside update_index;
# the format opens $db_file, mutates, and (via load) commits.
$format->update_index(
distribution => $distribution,
database => $db_file,
fetch => sub { $self->_fetch_dist_to_tmp( $_[0] ) }
);
$storage->publish_index( $db_file, $index );
unlink $db_file; # we received ownership from retrieve_index
return $self;
}
########################################################################
# delete_from_index: remove one distribution's rows from the index.
# retrieve -> update_index(delete_only) -> publish. Same locked round
# trip, no re-insert.
########################################################################
sub delete_from_index {
########################################################################
my ( $self, %args ) = @_;
my $distribution = $args{distribution}
or croak "ERROR: delete_from_index requires a distribution\n";
my $storage = $self->get_storage;
my $format = $self->get_format;
my $index = $self->_index_key;
my $guard = $storage->lock($index)
or croak "ERROR: could not acquire lock on $index\n";
my $db_file = $storage->retrieve_index( $index, '.db' );
$format->update_index(
distribution => $distribution,
database => $db_file,
delete_only => $TRUE,
fetch => sub { $self->_fetch_dist_to_tmp( $_[0] ) }
);
( run in 1.139 second using v1.01-cache-2.11-cpan-1236ad508bc )