You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bulk-processor/lib/NGCP/BulkProcessor/DSSorter.pm

189 lines
5.2 KiB

package NGCP::BulkProcessor::DSSorter;
use strict;
## no critic
# guarantee stability, regardless of algorithm
use sort 'stable';
use NGCP::BulkProcessor::Logging qw(getlogger);
use NGCP::BulkProcessor::LogError qw(sortconfigerror);
use NGCP::BulkProcessor::Table;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(
sort_by_config_ids
sort_by_configs
);
#my $logger = getlogger(__PACKAGE__);
sub new {
my $class = shift;
my $self = {};
$self->{sortconfig} = NGCP::BulkProcessor::Table->new();
bless($self,$class);
return $self;
}
sub add_sorting {
my $self = shift;
my ($sorting_id,$numeric,$dir,$memberchain) = @_;
if (defined $memberchain and ref $memberchain eq 'ARRAY') {
my @fieldnames = @$memberchain;
if ((scalar @fieldnames) > 0) {
$self->{sortconfig}->addrow_nodupe($numeric,$dir,@fieldnames);
}
} else {
sortconfigerror($sorting_id,'chain of object members undefined/invalid',getlogger(__PACKAGE__));
}
}
sub clear_sorting {
my $self = shift;
$self->{sortconfig}->clear();
}
sub sort_array {
my $self = shift;
my $array_ptr = shift;
my $sortconfig = $self->{sortconfig};
my $sorter = sub ($$) {
my $a = shift;
my $b = shift;
my $result = 0;
for (my $i = 0; $i < $sortconfig->rowcount(); $i++) {
my $j = 2;
my $membername = $sortconfig->element($i,$j);
my $item_a = ($a ? $a->{$membername} : undef);
my $item_b = ($b ? $b->{$membername} : undef);
$j++;
$membername = $sortconfig->element($i,$j);
while (defined $membername) {
$item_a = ($item_a ? $item_a->{$membername} : undef);
$item_b = ($item_b ? $item_b->{$membername} : undef);
$j++;
$membername = $sortconfig->element($i,$j);
}
$result = ($result or
(
$sortconfig->element($i,0) ?
($item_a <=> $item_b) : ($item_a cmp $item_b)
) * $sortconfig->element($i,1)
);
}
return $result;
};
my @sorted = ();
if (defined $array_ptr and ref $array_ptr eq 'ARRAY') {
@sorted = sort $sorter @$array_ptr;
}
return \@sorted;
}
sub sort_by_config_ids {
my ($array_ptr, $sorting_ids_ref, $sortingconfigurations) = @_;
if (defined $array_ptr and ref $array_ptr eq 'ARRAY') {
if (defined $sorting_ids_ref and ref $sorting_ids_ref eq 'ARRAY') {
if (defined $sortingconfigurations and
ref $sortingconfigurations eq 'HASH') {
my @sorting_ids = @{$sorting_ids_ref};
if ((scalar @sorting_ids) > 0) {
my $sorter = NGCP::BulkProcessor::DSSorter->new();
foreach my $sorting_id (@sorting_ids) {
my $sc = $sortingconfigurations->{$sorting_id};
if (defined $sc and ref $sc eq 'HASH') {
$sorter->add_sorting($sorting_id,
$sc->{numeric},
$sc->{dir},
$sc->{memberchain});
} else {
sortconfigerror($sorting_id,
'missing/invalid sorting configuration',
getlogger(__PACKAGE__));
}
}
return $sorter->sort_array($array_ptr);
}
} else {
sortconfigerror(undef,
'missing/invalid sorting configurations',
getlogger(__PACKAGE__));
}
}
return $array_ptr;
} else {
return [];
}
}
sub sort_by_configs {
my ($array_ptr,$sortingconfigurations) = @_;
if (defined $array_ptr and ref $array_ptr eq 'ARRAY') {
if (defined $sortingconfigurations and
ref $sortingconfigurations eq 'ARRAY') {
my @scs = @$sortingconfigurations;
if ((scalar @scs) > 0) {
my $sorter = NGCP::BulkProcessor::DSSorter->new();
my $sorting_id = -1;
foreach my $sc (@scs) {
#my $sc = $sortingconfigurations->{$sorting_id};
if (defined $sc and ref $sc eq 'HASH') {
$sorter->add_sorting($sorting_id,
$sc->{numeric},
$sc->{dir},
$sc->{memberchain});
} else {
sortconfigerror($sorting_id,
'invalid sorting configuration',
getlogger(__PACKAGE__));
}
$sorting_id -= 1;
}
return $sorter->sort_array($array_ptr);
}
}
return $array_ptr;
} else {
return [];
}
}
1;