This provides a default comparison function for items, letting them override it as appropriate for subclasses. Collection::GetSortedItems() then returns the collection's items sorted according to that order.
Signed-off-by: Francois Gouget fgouget@codeweavers.com --- testbot/lib/ObjectModel/Collection.pm | 22 +++++++++++ testbot/lib/ObjectModel/Item.pm | 53 ++++++++++++++++++++++++++ testbot/lib/WineTestBot/Patches.pm | 10 ++--- testbot/lib/WineTestBot/SpecialJobs.pm | 15 ++------ testbot/lib/WineTestBot/VMs.pm | 12 ++++++ 5 files changed, 94 insertions(+), 18 deletions(-)
diff --git a/testbot/lib/ObjectModel/Collection.pm b/testbot/lib/ObjectModel/Collection.pm index dd0be12d5..93a4502ef 100644 --- a/testbot/lib/ObjectModel/Collection.pm +++ b/testbot/lib/ObjectModel/Collection.pm @@ -395,6 +395,28 @@ sub GetItems($) =pod =over 12
+=item C<GetSortedItems()> + +Returns all the Item objects present in the Collection in the order defined +by the Item's Compare() method. + +See also GetItems() for the exact set of items being returned. + +=back +=cut + +sub GetSortedItems($$) +{ + my ($self, $Items) = @_; + + $self->Load() if (!$self->{Loaded}); + my @SortedItems = sort { $a->Compare($b) } values %{$self->{Items}}; + return @SortedItems; +} + +=pod +=over 12 + =item C<GetItemsCount()>
Returns how many Items are present in the Collection. diff --git a/testbot/lib/ObjectModel/Item.pm b/testbot/lib/ObjectModel/Item.pm index fb125f015..9cec7b47b 100644 --- a/testbot/lib/ObjectModel/Item.pm +++ b/testbot/lib/ObjectModel/Item.pm @@ -363,6 +363,59 @@ sub GetKey($) return $Key; }
+=pod +=over 12 + +=item C<Compare()> + +$A->Compare($B) return a negative, zero or positive value depending on whether +$A is less than, equal to, or greater than $B respectively. + +Neither object can be undefined, and both must be of the same type. + +The comparison is based on the Item's key fields which are compared in their +order in the property descriptors list, and based on their types (so numeric +comparison for numeric values, and alphabetical otherwise). + +Note that the comparison is not particularly optimised so if it is called +many times it would probably be more efficient to redefine it. + +=back +=cut + +sub Compare($$) +{ + my ($self, $B) = @_; + + foreach my $PropertyDescriptor (@{$self->{PropertyDescriptors}}) + { + next if (!$PropertyDescriptor->GetIsKey()); + + my $ColNames = $PropertyDescriptor->GetColNames(); + if ($PropertyDescriptor->GetClass() eq "Basic") + { + my $ColName = $ColNames->[0]; + my $ColType = $PropertyDescriptor->GetType(); + return ($ColType eq "N" or $ColType eq "S" or $ColType eq "DT") ? + $self->{ColValues}{$ColName} <=> $B->{ColValues}{$ColName} : + $self->{ColValues}{$ColName} cmp $B->{ColValues}{$ColName}; + } + if ($PropertyDescriptor->GetClass() eq "Enum") + { + my $ColName = $ColNames->[0]; + return $self->{ColValues}{$ColName} cmp $B->{ColValues}{$ColName}; + } + + # A Detailref cannot be a key so this is an Itemref + foreach my $ColName (@$ColNames) + { + my $Cmp = $self->{ColValues}{$ColName} cmp $B->{ColValues}{$ColName}; + return $Cmp if ($Cmp); + } + } + return 0; +} + sub GetFullKey($) { my ($self) = @_; diff --git a/testbot/lib/WineTestBot/Patches.pm b/testbot/lib/WineTestBot/Patches.pm index cc0fbe94a..6891fa509 100644 --- a/testbot/lib/WineTestBot/Patches.pm +++ b/testbot/lib/WineTestBot/Patches.pm @@ -268,12 +268,11 @@ sub Submit($$;$) my $WinVMs = CreateVMs(); $WinVMs->AddFilter("Type", $Bits eq "32" ? ["win32", "win64"] : ["win64"]); $WinVMs->AddFilter("Role", ["base"]); - my $SortedKeys = $WinVMs->SortKeysBySortOrder($WinVMs->GetKeys()); + my $SortedVMs = $WinVMs->GetSortedItems();
my $Tasks; - foreach my $VMKey (@$SortedKeys) + foreach my $VM (@$SortedVMs) { - my $VM = $WinVMs->GetItem($VMKey); my ($ErrMessage, $Missions) = ParseMissionStatement($VM->Missions); next if (defined $ErrMessage);
@@ -338,12 +337,11 @@ sub Submit($$;$) my $WineVMs = CreateVMs(); $WineVMs->AddFilter("Type", ["wine"]); $WineVMs->AddFilter("Role", ["base"]); - my $SortedKeys = $WineVMs->SortKeysBySortOrder($WineVMs->GetKeys()); + my $SortedVMs = $WineVMs->GetSortedItems();
my $Tasks; - foreach my $VMKey (@$SortedKeys) + foreach my $VM (@$SortedVMs) { - my $VM = $WineVMs->GetItem($VMKey); my ($ErrMessage, $Missions) = ParseMissionStatement($VM->Missions); next if (defined $ErrMessage);
diff --git a/testbot/lib/WineTestBot/SpecialJobs.pm b/testbot/lib/WineTestBot/SpecialJobs.pm index 360e1ffe8..e8677ecfd 100644 --- a/testbot/lib/WineTestBot/SpecialJobs.pm +++ b/testbot/lib/WineTestBot/SpecialJobs.pm @@ -54,10 +54,7 @@ sub GetReconfigVMs($$) $VMs->AddFilter("Name", [$VMKey]) if (defined $VMKey); $VMs->AddFilter("Type", [$VMType]); $VMs->FilterEnabledRole(); - - my $SortedKeys = $VMs->SortKeysBySortOrder($VMs->GetKeys()); - my @SortedVMs = map { $VMs->GetItem($_) } @$SortedKeys; - return @SortedVMs; + return $VMs->GetSortedItems(); }
sub AddReconfigJob($$$) @@ -132,10 +129,7 @@ sub GetWindowsTestVMs($$$) { $VMs->FilterEnabledRole(); } - - my $SortedKeys = $VMs->SortKeysBySortOrder($VMs->GetKeys()); - my @SortedVMs = map { $VMs->GetItem($_) } @$SortedKeys; - return @SortedVMs; + return $VMs->GetSortedItems(); }
sub AddWindowsTestJob($$$$$) @@ -219,10 +213,7 @@ sub GetWineTestVMs($) $VMs->AddFilter("Name", [$VMKey]) if (defined $VMKey); $VMs->AddFilter("Type", ["wine"]); $VMs->FilterEnabledRole(); - - my $SortedKeys = $VMs->SortKeysBySortOrder($VMs->GetKeys()); - my @SortedVMs = map { $VMs->GetItem($_) } @$SortedKeys; - return @SortedVMs; + return $VMs->GetSortedItems(); }
sub AddWineTestJob($$) diff --git a/testbot/lib/WineTestBot/VMs.pm b/testbot/lib/WineTestBot/VMs.pm index 65f633354..ee0c1be24 100644 --- a/testbot/lib/WineTestBot/VMs.pm +++ b/testbot/lib/WineTestBot/VMs.pm @@ -177,6 +177,18 @@ sub InitializeNew($$) $self->SUPER::InitializeNew($Collection); }
+sub Compare($$) +{ + my ($self, $B) = @_; + + # Sort retired and deleted VMs last + my %RoleOrders = ("retired" => 1, "deleted" => 2); + + return ($RoleOrders{$self->Role} || 0) <=> ($RoleOrders{$B->Role} || 0) || + $self->SortOrder <=> $B->SortOrder || + $self->Name <=> $B->Name; +} + sub HasEnabledRole($) { my ($self) = @_;