Arch

 view release on metacpan or  search on metacpan

perllib/Arch/SharedIndex.pm  view on Meta::CPAN

	});
	return $entries_updated;
}

sub query_index_list ($$) {
	my $self = shift;
	my $code = shift;

	my $file = $self->{file};
	if (!-f $file && $self->{can_create}) {
		open FH, ">$file" or die "Can't create index file ($file)\n";
		close FH;
	}
	-f $file or die "No index file ($file)\n";

	open FH, "+<$file" or die "Can't open $file for updating: $!\n";
	flock FH, 2;         # wait for exclusive lock
	seek FH, 0, 0;       # rewind to beginning
	my @content = <FH>;  # get current content
	chomp @content;

	my $index_list = [ grep { defined } map {
		/^(\d+)\t(.+?)\t(.*)/? [ $2, $3, $1 ]:
			warn("Corrupt line ($_) in $file; ignored\n"), undef
	} @content ];

	if ($self->{expiration}) {
		my $time = time();
		my $diff = $self->{expiration};
		my @expired_keys = map { $_->[0] }
			grep { $time - $_->[2] > $diff } @$index_list;
		$self->_do_delete($index_list, \@expired_keys) if @expired_keys;
	}

	# apply callback filter
	&$code($index_list);

	if ($self->{max_size} && @$index_list > $self->{max_size}) {
		my @excess_nums = (0 .. @$index_list - $self->{max_size} - 1);
		my @excess_keys = map { $_->[0] } (@$index_list)[@excess_nums];
		$self->_do_delete($index_list, \@excess_keys);
	}

	my @new_content = map { "$_->[2]\t$_->[0]\t$_->[1]" } @$index_list;
	my $is_changed = join('', @content) ne join('', @new_content);

	if ($is_changed) {
		seek FH, 0, 0;       # rewind again
		truncate FH, 0;      # empty the file
		print FH map { "$_$/" } @new_content;
	}
	close FH;            # release file
}

1;

__END__

=head1 NAME

Arch::SharedIndex - a synchronized data structure (map) for IPC

=head1 SYNOPSIS

    use Arch::SharedIndex;

    my $map = Arch::SharedIndex->new(file => "/tmp/logintimes.idx");
    my $time = time;
    $map->store(migo => $time - 75, bob => $time - 5, enno => $time);

    printf "All users: %s, %s, %s\n", $map->keys;
    printf "New users: %s\n", $map->grep(sub { $_[1] == $time });
    printf "Login time of migo: %s\n", $map->fetch('migo');

    $map->update(sub { $_[1] + 10 }, sub { $_[1] == $time });
    $map->store(migo => $time);
    $map->delete('bob');

    printf "Logged users with times: (%s)\n", join(", ", $map->hash);

=head1 DESCRIPTION

Arch::SharedIndex provides a key-value map that can be shared and
accessed safely by multiple processes.

=head1 METHODS

The following methods are available:

B<new>,
B<encode_value>,
B<decode_value>,
B<store_value>,
B<fetch_value>,
B<delete_value>,
B<store>,
B<fetch>,
B<delete>,
B<fetch_store>,
B<keys>,
B<values>,
B<hash>,
B<list>,
B<grep>,
B<filter>,
B<update>,
B<query_index_list>.

=over 4

=item B<new> I<options>

Create a new index object.  I<option> is a hash of parameters.

=over 4

=item B<file>

The path of the index file, used to store data.  Must not be omitted.

=item B<can_create>



( run in 1.665 second using v1.01-cache-2.11-cpan-5837b0d9d2c )