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);