Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

RFC: SlidingList::Changes

by Corion (Patriarch)
on Jan 29, 2003 at 20:52 UTC ( [id://231087]=perlmeditation: print w/replies, xml ) Need Help??

I've written some code that I think would be useful as a module, but I don't know what to name it. The code itself is quite simple, but it solves a problem I have quite often, convert sequential snapshots of a sliding window into one continouus list without unnecesary repetitions.

Some other names I did think about were :

  • Changes::SlidingList
  • SlidingWindow::Changes
  • Tail::SlidingWindow
  • Tail::Sliding
  • List::Sliding::Changes (suggested by PodMaster in the CB)
but I didn't find my ideas descriptive enough of what the module does (PodMasters suggestion isn't bad though). So I ask you to help me name this thing (and also to take an investigative look at it).



NAME

SlidingList::Changes - Extract new elements from a sliding window


SYNOPSIS

use strict; use SlidingList::Changes qw(find_new_elements); my $filename = 'log.txt'; tie @log, 'Tie::File', $filename or die "Couldn't tie to $filename : $!\n"; # See what has happened my @status = get_last_20_status_messages(); # Find out what we did not already communicate my (@new) = find_new_elements(\@log,\@status); print "New log messages : $_\n" for (@new); # And update our log with what we have seen push @log, @new;


DESCRIPTION

This module allows you to easily find elements that were appended to one of two lists. It is intended to faciliate processing wherever you don't have a log but only a sliding window for events, such as a status window which only displays the 20 most recent events, without timestamp.

The module assumes that the update frequency is high and will always respect the longest overlap between the two sequences. To be a bit faster with long lists, it searches the first list from the end, assuming that the first list will be much longer than the second list.


PUBLIC METHODS

find_new_indices( \@OLDLIST, \@NEWLIST [, EQUALITY] )

Returns the list of indices that were added since the last time @OLDLIST was updated. This is convenient if you want to modify @NEWLIST afterwards. The function accepts an optional third parameter, which should be a reference to a function that takes two list elements and compares them for equality.

find_new_elements( \@OLDLIST, \@NEWLIST [, EQUALITY] )

Returns the list of the elements that were added since the last time @OLDLIST was updated.


BUGS

More tests are always welcome !


AUTHOR

  Max Maischein <corion@cpan.org>


COPYRIGHT

Copyright (c) 2003 Max Maischein. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

The full text of the license can be found in the LICENSE file included with this module.


SEE ALSO

perl(1), File::Tail for a solution working only with files.


The module itself and its tests are available at http://www.corion.net/perl/SlidingList-Changes-0.01.tar.gz, and the module source itself is pasted below :
package SlidingList::Changes; use strict; use Exporter; use vars qw ($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); use Carp qw(croak); $VERSION = 0.01; @ISA = qw (Exporter); @EXPORT_OK = qw ( &find_new_indices &find_new_elements ); =head1 NAME SlidingList::Changes - Extract new elements from a sliding window =head1 SYNOPSIS use strict; use SlidingList::Changes qw(find_new_elements); my $filename = 'log.txt'; tie @log, 'Tie::File', $filename or die "Couldn't tie to $filename : $!\n"; # See what has happened since we last polled my @status = get_last_20_status_messages(); # Find out what we did not already communicate my (@new) = find_new_elements(\@log,\@status); print "New log messages : $_\n" for (@new); # And update our log with what we have seen push @log, @new; =head1 DESCRIPTION This module allows you to easily find elements that were appended to one of two lists. It is intended to faciliate processing wherever you don't have a log but only a sliding window for events, such as a status window which only displays the 20 most recent events, without timestamp. The module assumes that the update frequency is high and will always respect the longest overlap between the two sequences. To be a bit faster with long lists, it searches the first list from the end, assuming that the first list will be much longer than the second list. =head1 PUBLIC METHODS find_new_indices( \@OLDLIST, \@NEWLIST [, EQUALITY] ) Returns the list of indices that were added since the last time @OLDLI +ST was updated. This is convenient if you want to modify @NEWLIST afterwa +rds. The function accepts an optional third parameter, which should be a reference to a function that takes two list elements and compares them for equality. find_new_elements( \@OLDLIST, \@NEWLIST [, EQUALITY] ) Returns the list of the elements that were added since the last time @ +OLDLIST was updated. =cut sub find_new_indices { my ($old,$new,$equal) = @_; croak "First parameter to find_new_elements() must be a reference, n +ot $old" unless ref $old; croak "Second parameter to find_new_elements() must be a reference, +not $new" unless ref $new; $equal ||= sub { $_[0] eq $_[1] }; my ($new_offset,$old_offset) = (0,scalar @$old - scalar @$new); $old_offset = 0 if $old_offset < 0; while ($old_offset < scalar @$old) { $new_offset = 0; while (($old_offset+$new_offset < scalar @$old) and ($new_offset < scalar @$new) and ($equal->($old->[$old_offset+$new_offset],$new->[$new_offse +t]))) { $new_offset++; }; last if ($old_offset+$new_offset == scalar @$old); $old_offset++; }; ($new_offset .. $#$new) }; sub find_new_elements { my ($old,$new,$equal) = @_; croak "First parameter to find_new_elements() must be a reference, n +ot $old" unless ref $old; croak "Second parameter to find_new_elements() must be a reference, +not $new" unless ref $new; (@{$new}[ find_new_indices($old,$new,$equal) ]) }; 1; __END__ =head1 BUGS More tests are always welcome ! =head1 AUTHOR Max Maischein <corion@cpan.org> =head1 COPYRIGHT Copyright (c) 2003 Max Maischein. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. The full text of the license can be found in the LICENSE file included with this module. =head1 SEE ALSO perl(1), L<File::Tail> for a solution working only with files.

20030130 - Edit: Added PodMasters suggestion from the CB

perl -MHTTP::Daemon -MHTTP::Response -MLWP::Simple -e ' ; # The $d = new HTTP::Daemon and fork and getprint $d->url and exit;#spider ($c = $d->accept())->get_request(); $c->send_response( new #in the HTTP::Response(200,$_,$_,qq(Just another Perl hacker\n))); ' # web

Replies are listed 'Best First'.
Re: RFC: SlidingList::Changes
by Aragorn (Curate) on Jan 30, 2003 at 15:38 UTC
    What about Lists::Changes or Changes::Lists?

    Arjen

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://231087]
Approved by ChemBoy
Front-paged by Tanalis
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2024-04-16 23:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found