File-RoundRobin
view release on metacpan or search on metacpan
lib/File/RoundRobin.pm view on Meta::CPAN
CORE::syswrite($fh,"1"."\x00");
#file size
CORE::syswrite($fh,$params{size} ."\x00");
#where is the start of the file
$start_point = length($params{size}) * 2 + 2 + 2;
CORE::syswrite($fh,("0" x (length($params{size}) - length($start_point) )) . $start_point ."\x00");
$headers_size = length($params{size}) * 2 + 2 + 2;
$read_only = 0;
}
else {
if ($params{mode} eq "append") {
if (! open($fh,"+<",$params{path}) ) {
$@ = $!;
return;
}
CORE::binmode($fh,":unix");
CORE::sysseek($fh,0,0);
$read_only = 0;
}
elsif ($params{mode} eq "read") {
if (! open($fh,"<",$params{path}) ) {
$@ = $!;
return;
}
CORE::binmode($fh,":unix");
$read_only = 1;
}
else {
$@ = "Invalid open mode! Use one of new | read | append!";
return;
}
my $start_section;
CORE::sysread($fh,$start_section,4096);
($version, $size, $start_point) = split("\x00", $start_section);
CORE::sysseek($fh,0,0);
#make sure this looks like a File::RoundRobin file
if (! $version || $version ne "1" || int($size || '') == 0 || int($start_point || '') == 0 ) {
$@ = "File does not look like a File::RoundRobin file - missing headers";
return;
}
$headers_size = length($version) + length($size) + length($start_point) +3;
# +3 because of the 3 \x00 chars we use to separate headder info
CORE::sysseek($fh,$start_point + 0,0);
}
return ($fh,$size + 0,$start_point + 0,$headers_size + 0,$read_only);
}
=head2 update_headers
Update the start point in the headers section after a write command
=cut
sub update_headers {
my $self = shift;
my $fh = $self->{_fh_};
CORE::sysseek($fh,0, 0);
my $headers = '';
#version
$headers .= "1\x00";
#file size
$headers .= $self->{_data_length_} ."\x00";
#start pos
$headers .= ("0" x (length($self->{_data_length_}) - length($self->{_write_start_point_}) )) . $self->{_write_start_point_} ."\x00";
CORE::syswrite($fh,$headers);
#go back to the previous position
CORE::sysseek($fh,$self->{_write_start_point_}, 0);
}
=head2 refresh
Re-reads the headers from the file. Useful for tail
=cut
sub refresh {
my $self = shift;
my $fh = $self->{_fh_};
my $pos = $self->tell();
CORE::sysseek($fh,0,0);
local $/ = "\x00";
#skip the first part of the header
my $version = <$fh>;
my $size = <$fh>;
my $start_point = <$fh>;
my $headers_size = length($version) + length($size) + length($start_point);
$size =~ s/\x00//g;
$start_point =~ s/\x00//g;
$self->{_headers_size_} = $headers_size;
$self->{_read_start_point_} = $start_point + 0;
$self->{_data_length_} = $size + 0;
$self->{_file_length_} = $size + $headers_size;
CORE::sysseek($fh,$start_point,0);
}
=head2 sync_markers
Sets the write market to the same position as the read marker
( run in 0.729 second using v1.01-cache-2.11-cpan-39bf76dae61 )