use strict;
use warnings;
my @bigarray = ( # Think @{$matches{$element}{$sitekey}}
1 .. 15, 21 .. 100, 200 .. 2000, 2010 .. 2015
);
test (1, 12);
test (10, 20);
test (18, 25);
test (2000, 3000);
sub test {
my $lowIndex = BinSearch ($_[0], \&cmpFunc, \@bigarray) + 0.5;
my $highIndex = BinSearch ($_[1], \&cmpFunc, \@bigarray);
my @arrayA = @bigarray[$lowIndex..$highIndex];
print "$_[0] - $_[1]: [$lowIndex .. $highIndex]: @arrayA\n";
}
sub cmpFunc {
$_[0] <=> $_[1];
}
sub BinSearch {
my ($target, $cmp, $array) = @_;
my $posmin = 0;
my $posmax = $#$array;
return -0.5 if $cmp->($array->[0], $target) > 0;
return $#$array + 0.5 if &$cmp ($array->[-1], $target) < 0;
while (1) {
my $mid = int (($posmin + $posmax) / 2);
my $result = $cmp->($array->[$mid], $target);
if ($result < 0) {
$posmin = $posmax, next if $mid == $posmin && $posmax != $posmin;
return $mid + 0.5 if $mid == $posmin;
$posmin = $mid;
} elsif ($result > 0) {
$posmax = $posmin, next if $mid == $posmax && $posmax != $posmin;
return $mid - 0.5 if $mid == $posmax;
$posmax = $mid;
} else {
return $mid;
}
}
}
####
1 - 12: [0 .. 11]: 1 2 3 4 5 6 7 8 9 10 11 12
10 - 20: [9 .. 14.5]: 10 11 12 13 14 15
18 - 25: [15 .. 19]: 21 22 23 24 25
2000 - 3000: [1895 .. 1901.5]: 2000 2010 2011 2012 2013 2014 2015
####
my $lowIndex = BinSearch ($lowerlimit, sub {$_[0] <=> $_[1]}, $matches{$element}{$sitekey}) + 0.5;
my $highIndex = BinSearch ($upperlimit, sub {$_[0] <=> $_[1]}, $matches{$element}{$sitekey});
my @arrayA = @{$matches{$element}{$sitekey}}[$lowIndex..$highIndex];