use strict;
use warnings;
require Tie::VecArray;
my $vec = '';
my @array;
vec($vec, $_, 4 ) = rand(16) for 0 .. 99;
print join(" ", map{ vec( $vec, $_, 4) } 0 .. 99);
print "\n";
my $obj = tie @array, 'Tie::VecArray', 4, $vec;
@array = sort {$a <=> $b} @array;
print join(" ", map{ vec( $vec, $_, 4) } 0 .. 99);
####
package Tie::PGVecArray;
use strict;
use warnings;
use Tie::Array;
use POSIX qw(ceil);
use base qw(Tie::Array);
use fields qw(bits vec size);
sub _IDX2BYTES {
my $self = shift;
my $idx = shift;
#define _IDX2BYTES($self, $idx) \
ceil($idx * ($self->{bits}/8))
}
sub _BYTES2IDX {
my $self = shift;
my $bytes = shift;
#define _BYES2IDX($self, $bytes) \
ceil($bytes * 8 / $self->{bits})
}
sub TIEARRAY {
my($class, $bits, $vec) = @_;
no strict 'refs';
my $self = bless [\%{$class.'::FIELDS'}], $class;
$self->{bits} = $bits;
$self->{vec} = $vec;
$self->{size} = _BYTES2IDX($self, length $$vec);
return $self;
}
sub FETCH {
my $self = shift;
return vec(${$self->{vec}}, $_[0], $self->{bits});
}
sub STORE {
my $self = shift;
$self->{size} = $_[0] + 1 if $self->{size} < $_[0] + 1;
return vec(${$self->{vec}}, $_[0], $self->{bits}) = $_[1];
}
sub FETCHSIZE {
my $self = shift;
return $self->{size};
}
sub STORESIZE {
my $self = shift;
my $new_size = shift;
if( $self->{size} > $new_size ) {
my $new_length = _IDX2BYTES($self, $new_size);
substr(${$self->{vec}}, $new_length) = '' if
$new_length < length ${$self->{vec}};
}
$self->{size} = $new_size;
}
1;
####
use strict;
use warnings;
require Tie::PGVecArray;
my $vec = '';
my @array;
vec($vec, $_, 4 ) = rand(16) for 0 .. 99;
print join(" ", map{ vec( $vec, $_, 4) } 0 .. 99);
print "\n";
my $obj = tie @array, 'Tie::PGVecArray', 4, \$vec;
@array = sort {$a <=> $b} @array;
print join(" ", map{ vec( $vec, $_, 4) } 0 .. 99);