summaryrefslogtreecommitdiff
path: root/fml/lib/File
diff options
context:
space:
mode:
authorfukachan <fukachan>2001-02-21 11:06:03 +0000
committerfukachan <fukachan>2001-02-21 11:06:03 +0000
commitb303645f803dd4e69af72598e4d933b4f366aa49 (patch)
tree3fd7673130d14b8719babf246feee87cfd7e9d65 /fml/lib/File
parent1e8c7cd38a2f8339116ed7a1951fb8770ee8703d (diff)
downloadfml8-b303645f803dd4e69af72598e4d933b4f366aa49.tar.gz
fml8-b303645f803dd4e69af72598e4d933b4f366aa49.tar.bz2
fml8-b303645f803dd4e69af72598e4d933b4f366aa49.zip
add prototype
Diffstat (limited to 'fml/lib/File')
-rw-r--r--fml/lib/File/RingBuffer.pm132
-rw-r--r--fml/lib/File/Rotate.pm139
2 files changed, 271 insertions, 0 deletions
diff --git a/fml/lib/File/RingBuffer.pm b/fml/lib/File/RingBuffer.pm
new file mode 100644
index 00000000..04faebda
--- /dev/null
+++ b/fml/lib/File/RingBuffer.pm
@@ -0,0 +1,132 @@
+#-*- perl -*-
+#
+# Copyright (C) 2001 Ken'ichi Fukamachi
+# All rights reserved. This program is free software; you can
+# redistribute it and/or modify it under the same terms as Perl itself.
+#
+# $Id$
+# $FML$
+#
+
+package File::RingBuffer;
+use strict;
+use vars qw(@ISA @EXPORT @EXPORT_OK $AUTOLOAD);
+use Carp;
+use IO::File;
+
+=head1 NAME
+
+File::RingBuffer - IO operations to ring buffer which consists of files
+
+=head1 SYNOPSIS
+
+ ... lock e.g. by flock(2) ...
+
+ use File::RingBuffer;
+ $obj = new File::RingBuffer {
+ directory => '/some/where'
+ };
+ $fh = $obj->open;
+ print $fh $message;
+ $fh->close;
+
+ ... unlock ...
+
+=head1 DESCRIPTION
+
+To log messages but up to some limit, it is useful to use the ring of
+files as a buffer.
+
+Consider several files under a directory C<ring/>
+where the unit of the ring is 5 here.
+C<ring/> may have 5 files in it.
+
+ 0 1 2 3 4
+
+To log a message is to write it to one of them.
+At the first time the message is logged to the file C<1>,
+and next time to C<2> and so on.
+If all 5 files are used, pick up and use (overwrite) the oldest one.
+The oldest one is C<0>.
+
+We use a file in cyclic way as follows:
+
+ 0 -> 1 -> 2 -> 3 -> 4 -> 0 -> 1 -> ...
+
+We expires the old data.
+A file name is a number for simplicity.
+The latest number is holded in C<ring/.seq> file (C<.seq> in that
+direcotry by default) and truncated to 0 by the modulus C<5>.
+
+=head1 METHODS
+
+=cut
+
+
+require Exporter;
+@ISA = qw(IO::File);
+
+BEGIN {}
+END {}
+
+
+sub new
+{
+ my ($self, $args) = @_;
+ my ($type) = ref($self) || $self;
+ my $me = {};
+
+ $me->{ _directory } = $args->{ directory };
+ $me->{ _modulus } = $args->{ modulus } || 128;
+ $me->{ _sequence_file_name } = $args->{ sequence_file_name } || '.seq';
+
+ return bless $me, $type;
+}
+
+
+sub open
+{
+ my ($self) = @_;
+ my $seq_file = $self->{ _directory } ."/". $self->{ _sequence_file_name };
+ my $modulus = $self->{ _modulus } || 128;
+
+ use File::Sequence;
+ my $sfh = new File::Sequence {
+ sequence_file => $seq_file,
+ modulus => $modulus,
+ };
+ my $id = $sfh->increment_id;
+ my $file = $self->{ _directory } ."/". $id;
+ my $mode = 'w';
+
+ new IO::File $file, $mode;
+}
+
+
+sub close
+{
+ my ($self) = @_;
+ $self->SUPER::close();
+}
+
+
+=head1 AUTHOR
+
+Ken'ichi Fukamachi
+
+=head1 COPYRIGHT
+
+Copyright (C) 2001 Ken'ichi Fukamachi
+
+All rights reserved. This program is free software; you can
+redistribute it and/or modify it under the same terms as Perl itself.
+
+=head1 HISTORY
+
+File::RingBuffer appeared in fml5 mailing list driver package.
+See C<http://www.fml.org/> for more details.
+
+=cut
+
+
+1;
diff --git a/fml/lib/File/Rotate.pm b/fml/lib/File/Rotate.pm
new file mode 100644
index 00000000..9437f05a
--- /dev/null
+++ b/fml/lib/File/Rotate.pm
@@ -0,0 +1,139 @@
+#-*- perl -*-
+#
+# Copyright (C) 2001 Ken'ichi Fukamachi
+# All rights reserved. This program is free software; you can
+# redistribute it and/or modify it under the same terms as Perl itself.
+#
+# $Id$
+# $FML$
+#
+
+package File::Rotate;
+use strict;
+use vars qw(@ISA @EXPORT @EXPORT_OK);
+use Carp;
+
+BEGIN {}
+END {}
+
+=head1 NAME
+
+IO::Rotate - IO with rotate operations
+
+=head1 SYNOPSIS
+
+ $obj = new IO::Rotate {
+ max_size => 10000,
+ num_backlog => 4,
+ };
+ $obj->rotate( \@target_files );
+
+=head1 DESCRIPTION
+
+library to wrap Rotate IO operations.
+It automatically rotates $file in close() operation.
+C<rotation> rearranges files like this:
+
+ rm file.4
+ mv file.3 file.4
+ mv file.2 file.3
+ mv file.1 file.2
+ mv file.0 file.1
+ mv file file.0
+
+=cut
+
+# Descriptions: constructor
+# forward new() request to superclass (IO::File)
+# Arguments: $class_name $HASH_REFERENCE
+# Side Effects: none
+# Return Value: class object
+# XXX $self is blessed file handle.
+sub new
+{
+ my ($self, $args) = shift;
+ my ($type) = ref($self) || $self;
+ my $me = {};
+
+ if ( ref($args->{ file_list }) eq 'ARRAY' ) {
+ $me->{ _file_list } = $args->{ file_list };
+ }
+ $me->{ _max_size } = $args->{ max_size } || 300*1024;
+ $me->{ _num_backlog } = $args->{ num_backlog } || 4;
+
+ return bless $me, $type;
+}
+
+
+sub is_time_to_rotate
+{
+ my ($self) = @_;
+ my ($file, $size, $max) = $self->_get_param();
+
+ use File::stat;
+ my $st = stat($file);
+
+ return 1 if $st->size > $size;
+ return 0;
+}
+
+
+sub rotate
+{
+ my ($self) = @_;
+ my ($file, $size, $max) = $self->_get_param();
+
+ # remove oldest file
+ my $maxfile = $file.".".$max;
+ if (-f $maxfile) { unlink $maxfile;}
+
+ # mv var/log/file.3 -> var/log/file.4 ...;
+ do {
+ my $old = "$file.".($max - 1 > 0 ? $max - 1 : 0);
+ my $new = "$file.".($max);
+ print STDERR "rename($old, $new)" if -f $old;
+ -f $old && rename($old, $new);
+ $max--;
+ } while ($max > 0);
+}
+
+
+sub _get_param
+{
+ my ($self) = @_;
+ (${*$self}{_file}, ${*$self}{_max_size}, ${*$self}{_num_backlog});
+}
+
+
+# Descriptions: return error message
+# Arguments: $self
+# XXX $self is blessed file handle.
+# Side Effects: none
+# Return Value: error message string
+sub error
+{
+ my ($self) = @_;
+ my $fh = $self;
+ ${ *$fh }{ _error };
+}
+
+
+=head1 AUTHOR
+
+Ken'ichi Fukamachi
+
+=head1 COPYRIGHT
+
+Copyright (C) 2001 Ken'ichi Fukamachi
+
+All rights reserved. This program is free software; you can
+redistribute it and/or modify it under the same terms as Perl itself.
+
+=head1 HISTORY
+
+File::Rotate appeared in fml5 mailing list driver package.
+See C<http://www.fml.org/> for more details.
+
+=cut
+
+1;