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.
189 lines
5.2 KiB
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;
|