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 )