#! perl -slw use strict; package Tie::Array::CountReads; use Tie::Array; our @ISA = 'Tie::Array'; my %readCounts; sub TIEARRAY{ my $self = bless [], $_[ 0 ]; $readCounts{ $self } = 0; return $self; } sub FETCH { ++$readCounts{ $_[0] }; $_[0]->[ $_[1] ] } sub FETCHSIZE{ scalar @{ $_[0] } } sub STORESIZE{ $#{ $_[0] } = $_[1] } sub STORE{ $_[0]->[ $_[ 1 ] ] = $_[ 2 ] } sub readCount{ $readCounts{ $_[ 0 ] } } sub resetCount{ $readCounts{ $_[0] } = 0 } package main; my $ramping = 57000 - 9029; my $step = int( $ramping / 72 ); my $leftovers = $ramping - ( $step * 72 ); my $tiedObj = tie my @levels, 'Tie::Array::CountReads'; @levels = ( ( 68 ) x 9029, map( (( $_ ) x $step ), reverse 0 .. 71 ), (0) x $leftovers ); #print scalar @levels; sub probe { use integer; my( $aref, $lo, $hi, $limit, $istep ) = @_; my $step = ( $hi - $lo ) / $istep; { my $i = $lo; $i += $step while $i <= $hi and $aref->[ $i ] <= $limit; if( $i >= $hi ) { if( $aref->[ $hi ] == $limit ) { --$hi while $aref->[ $hi - 1 ] == $limit; return $hi; } $step /= 2; } else { $limit = $aref->[ $i ]; $lo = $hi - $step; ## Update: Swapped the order of this line and the next $hi = $i; $step = int( ( $hi - $lo ) / $istep ); # $istep was wrongly '10' } redo; } } for my $istep ( 10 .. 100 ) { printf "Initial step size: $istep located 'file' %d after probing %d files\n", probe( \@levels, 0, $#levels, 68, $istep ), $tiedObj->readCount; $tiedObj->resetCount; } for my $istep ( map $_ *10, 10 .. 100 ) { printf "Initial step size: $istep located 'file' %d after probing %d files\n", probe( \@levels, 0, $#levels, 68, $istep ), $tiedObj->readCount; $tiedObj->resetCount; }