App-SimpleBackuper

 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 distribution
 view release on metacpan -  search on metacpan

( run in 0.843 second using v1.00-cache-2.02-grep-82fe00e-cpan-9e6bc14194b )