OLE::Storage::Iolist - Data management for OLE::Storage::Io (I<alpha>)


OLE-Storage documentation Contained in the OLE-Storage distribution.

Index


Code Index:

NAME

Top

OLE::Storage::Iolist - Data management for OLE::Storage::Io (alpha)

SYNOPSIS

Top

use OLE::Storage::Iolist();

s.b.

DESCRIPTION

Top

Note: OLE::Storage uses Iolists in conjuntion with Io interface for IO operations. An IO entry is a two element list like ($offset, $length).

aggregate

$NewIolist = $IoL -> aggregate ($method)

Sorts and merges Iolist $IoL, returns the new packed Iolist $NewIolist. Returns an empty Iolist on errors (!to be changed!). $method can be:

   method	sort offsets	allow offset overlaps
   1		yes		no
   2		yes		yes
   3		no		no
   4		no		yes

append

($o1, $l1) == $IoL -> append ($o, $l)

Appends an entry to Iolist. Tries to merge the Iolists last entry with the new one. Returns the new last entry of Iolist.

entry

($o, $l) = $IoL -> entry ($i)

rval: Get entry number $i.

($o, $l) == $IoL -> entry ($i, $o, $l)

lval: Set entry number $i to ($o, $l). Returns this entry.

length

($l) = $IoL -> length ($i)

rval: Get length of entry number $i.

$l == $IoL -> length ($i, $l)

lval: Set length of entry number $i to $l. Returns $l.

max  

$num = $IoL -> max ()

Returns number of $IoL's entries.

new  

$IoL = new Iolist ([\@offset, \@length])

Iolist constructor. Returns an Iolist handle. Can be initialized with references to corresponding offset and length lists.

offset

($o) = $IoL -> offset ($i)

rval: Get offset of entry number $i.

$o == $IoL -> offset ($i, $o)

lval: Set offset of entry number $i to $o. Returns $o.

push

1 == $IoL -> push ($AnotherIolist)

Appends all entries of $AnotherIolist to $IoL.

sumlen

$length = $IoL -> sumlen ()

Returns total length of $IoL's entries.

SEE ALSO

Top

OLE::Storage::Io

AUTHOR

Top

Martin Schwartz <schwartz@cs.tu-berlin.de>


OLE-Storage documentation Contained in the OLE-Storage distribution.

#
# $Id: Iolist.pm,v 1.1.1.1 1998/02/25 21:13:00 schwartz Exp $
#
# Iolist
#
# Copyright (C) 1997, 1998 Martin Schwartz 
#
# (POD documentation at end of file)
#
# Contact: schwartz@cs.tu-berlin.de
#

package OLE::Storage::Iolist;
use strict;
my $VERSION=do{my@R=('$Revision: 1.1.1.1 $'=~/\d+/g);sprintf"%d."."%d"x$#R,@R};

sub new {
   my ($proto, $oR, $lR) = @_;
   my $class = ref($proto) || $proto;
   my $S = {  
      O => $oR || [],
      L => $lR || []
   };
   bless ($S, $class);
}

sub dump {
   my ($S) = @_;
   if (@{$S->{O}}) {
      print "Iolist = \n";
      for (0..$#{$S->{O}}) {
         printf "  %03x: O=%6x  L=%x\n", $_, $S->{O}->[$_], $S->{L}->[$_];
      }
   } else {
      print "No Iolist.\n";
   }
   print "\n";
1}

sub append {
   my ($S, $o, $l) = @_;
   my $max = max($S);
   my ($o1, $l1) = entry($S, $max) if $max!=-1;
   if (($max==-1) || (($o1+$l1) != $o)) {
      push ( @{$$S{O}}, $o );
      push ( @{$$S{L}}, $l );
   } else {
      entry($S, $max, $o1, $l1+$l);
   }
}

sub push {
   my ($S, $sR) = @_;
   if ($sR && $S) {
      push ( @{$$S{O}}, @{$$sR{O}} );
      push ( @{$$S{L}}, @{$$sR{L}} );
   }
1}

sub entry {
   my ($S, $i) = (shift, shift);
   ($$S{O}[$i], $$S{L}[$i]) = (shift, shift) if @_;
   ($$S{O}[$i], $$S{L}[$i]);
}
sub length {my ($S, $i) = (shift, shift); $$S{L}[$i] = shift if @_; $$S{L}[$i]}
sub offset {my ($S, $i) = (shift, shift); $$S{O}[$i] = shift if @_; $$S{O}[$i]}
sub max    {my $S = shift; $#{$$S{O}} }

#
# ----- aggregate methods -----
#

sub sumlen {
   my $S = shift;
   my $size = 0;
   for (@{$$S{L}}) { 
      $size += $_;
   }
   $size;
}

sub aggregate {
#
# $iolistO = aggregate (method)
#
# method:  
#    1  @offsets shall be sorted, no overlap allowed
#    2  @offsets shall be sorted, overlap is allowed
#    3  @offsets are sorted, no overlap allowed
#    4  @offsets are sorted, overlap is allowed
#
   my ($S, $method) = @_;
   my $empty = $S->new();
   return $empty if ($method<1)||($method>4); # Don't know method!

   my ($o, $o1, $l, $l1);
   my %o_in  = ();
   my $o_in  = $S->new();
   my $o_out = $S->new();

   #
   # Sort
   #
   if ( ($method==1) || ($method==2)) {
      # sort offsets
      for (0 .. $S->max()) {
         ($o, $l) = $S->entry($_);
         next if !$l;
         if (defined $o_in{$o}) {
            return $empty if $method==1; # Data chunks overlap!
            $o_in{$o}=$_ if $l>$o_in{$o};
         } else {
            $o_in{$o}=$_;
         }
      } 
      for (sort {$a <=> $b} keys %o_in) {
         $o_in->append($S->entry($o_in{$_}));
      }
   } else {
      $o_in = $S;
   }

   #
   # Aggregate
   #
   ($o, $l) = $o_in->entry(0);

   for (1 .. $o_in->max()+1) {
      ($o1, $l1) = $o_in->entry($_);

      if ( ($_==($o_in->max()+1)) 
         || ( $o1 < $o )
         || ( $o1 > ($o+$l) )
      ) {
         $o_out->append($o, $l);
         ($o, $l) = ($o1, $l1);
      } elsif ( $o1 < ($o+$l) ) {
         return $empty if ($method==1 || $method==3); # Data chunks overlap! 
         if ( ($o1+$l1) > ($o+$l) ) {
            $l=$o1+$l1-$o;
         }
      } else {
         $l += $l1;
      }
   }
   $o_out;
}

"Atomkraft? Nein, danke!"

__END__