App-SimpleBackuper
view release on metacpan - search on metacpan
view release on metacpan or search on metacpan
lib/App/SimpleBackuper/DB/BaseTable.pm view on Meta::CPAN
package App::SimpleBackuper::DB::BaseTable;
use strict;
use warnings FATAL => qw( all );
use Carp;
use Data::Dumper;
sub new {
my($class, $number_of_records) = @_;
$number_of_records //= 0;
my @arr = (undef) x $number_of_records;
return bless \@arr => $class;
}
sub find_row {
my $self = shift;
my($from, $to) = $self->_find(@_);
die "Found more then one" if $to > $from;
return undef if $from > $to;
return $self->unpack( $self->[ $from ] );
}
sub find_all {
my($self) = shift;
my($from, $to) = $self->_find(@_);
#warn "$self->_find(@_): from=$from, to=$to";
#warn "self=[@$self]";
my @result = map { $self->unpack( $self->[ $_ ] ) } $from .. $to;
return \@result;
}
# Binary search
# Parameters:
# 0 - search query us hashref with fields & values.
# Packed record must begins on this fields.
# All fields must be a fixed width when packed.
# Result:
# [0] - index of begin of range of matches;
# [1] - index of end of range of matches;
# For empty array result always is 0, -1.
# If nothing found, you can insert new value with queried fields values to index of begin of range of matches and it not broke sorting
sub _find {
my($self, $data) = @_;
return 0, -1 if ! @$self;
$data = $self->pack($data) if ref($data);
my($from, $to, $min_from, $min_to, $max_from, $max_to) = (undef, undef, 0, 0, $#$self, $#$self);
while(! defined $from or ! defined $to) {
my $mid_from = int($min_from + ($max_from - $min_from) / 2);
my $mid_to = int($min_to + ($max_to - $min_to) / 2);
my $cmp;
if(! defined $from) {
$cmp = $data cmp substr( $self->[ $mid_from ], 0, length($data) );
if($cmp == -1) { # data < mid_from
if($mid_from == 0) {
return 0, -1;
} else {
$cmp = $data cmp substr( $self->[ $mid_from - 1 ], 0, length($data) );
if($cmp == -1) { # data < mid_from-1
$max_from = $mid_from - 1;
return 0, -1 if $max_from < 0;
}
elsif($cmp == 1) { # data > mid_from-1
return $mid_from, $mid_from - 1;
}
else { # data = mid_from-1
$max_from = $to = $mid_from - 1;
}
view all matches for this distributionview release on metacpan - search on metacpan
( run in 0.843 second using v1.00-cache-2.02-grep-82fe00e-cpan-9e6bc14194b )