From 27ea4759845a5392fc2372628da10abe410583a7 Mon Sep 17 00:00:00 2001 From: DanB Date: Thu, 17 Oct 2024 13:46:23 +0200 Subject: [PATCH] Adding RankingS Ascendent Sorter --- engine/librankings.go | 56 ++++++++++++++++++++++++++++++++++++-- engine/librankings_test.go | 21 ++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/engine/librankings.go b/engine/librankings.go index c87ea2d23..765426c8d 100644 --- a/engine/librankings.go +++ b/engine/librankings.go @@ -123,8 +123,9 @@ func newRankingSorter(sortingType string, sortingParams []string, return case utils.MetaDesc: return newRankingDescSorter(sortingParams, statMetrics), nil + case utils.MetaAsc: + return newRankingAscSorter(sortingParams, statMetrics), nil } - return } // newRankingDescSorter is a constructor for rankingDescSorter @@ -140,7 +141,7 @@ func newRankingDescSorter(sortingParams []string, return } -// rankingDescSorter will sort data descendently for metrics in sortingParams or randomly if all equal +// rankingDescSorter will sort data descendent for metrics in sortingParams or random if all equal type rankingDescSorter struct { sortingParams []string statMetrics map[string]map[string]float64 @@ -177,3 +178,54 @@ func (rkDsrtr *rankingDescSorter) sortStatIDs() []string { }) return rkDsrtr.statIDs } + +// newRankingAscSorter is a constructor for rankingAscSorter +func newRankingAscSorter(sortingParams []string, + statMetrics map[string]map[string]float64) (rkASrtr *rankingAscSorter) { + rkASrtr = &rankingAscSorter{ + sortingParams, + statMetrics, + make([]string, 0, len(statMetrics))} + for statID := range rkASrtr.statMetrics { + rkASrtr.statIDs = append(rkASrtr.statIDs, statID) + } + return +} + +// rankingAscSorter will sort data ascendent for metrics in sortingParams or randomly if all equal +type rankingAscSorter struct { + sortingParams []string + statMetrics map[string]map[string]float64 + + statIDs []string // list of keys of the statMetrics +} + +// sortStatIDs implements rankingSorter interface +func (rkASrtr *rankingAscSorter) sortStatIDs() []string { + if len(rkASrtr.statIDs) == 0 { + return rkASrtr.statIDs + } + sort.Slice(rkASrtr.statIDs, func(i, j int) bool { + for _, metricID := range rkASrtr.sortingParams { + val1, hasMetric1 := rkASrtr.statMetrics[rkASrtr.statIDs[i]][metricID] + if !hasMetric1 { + return false + } + val2, hasMetric2 := rkASrtr.statMetrics[rkASrtr.statIDs[j]][metricID] + if !hasMetric2 { + return true + } + //in case we have the same value for the current metricID we skip to the next one + if val1 == val2 { + continue + } + if val2 > val1 { + return true + } + return false + } + //in case that we have the same value for all params we return randomly + return utils.BoolGenerator().RandomBool() + }) + return rkASrtr.statIDs +} diff --git a/engine/librankings_test.go b/engine/librankings_test.go index 5fe4e8cbb..46234eb89 100644 --- a/engine/librankings_test.go +++ b/engine/librankings_test.go @@ -43,3 +43,24 @@ func TestRankingDescSorterSortStatIDs(t *testing.T) { t.Errorf("Expecting: %v, received %v", eStatIDs, statIDs) } } + +func TestRankingAscSorterSortStatIDs(t *testing.T) { + statMetrics := map[string]map[string]float64{ + "STATS1": {"*acc": 12.1, "*tcc": 24.2}, + "STATS2": {"*acc": 12.1, "*tcc": 24.3}, + "STATS3": {"*acc": 10.1, "*tcc": 25.3}, + "STATS4": {"*tcc": 26.3}, + } + sortMetrics := []string{"*acc", "*tcc"} + rtAscSrtr := newRankingAscSorter(sortMetrics, statMetrics) + eStatIDs := []string{"STATS3", "STATS1", "STATS2", "STATS4"} + if statIDs := rtAscSrtr.sortStatIDs(); !reflect.DeepEqual(eStatIDs, statIDs) { + t.Errorf("Expecting: %v, received %v", eStatIDs, statIDs) + } + sortMetrics = []string{"*tcc", "*acc"} + rtAscSrtr = newRankingAscSorter(sortMetrics, statMetrics) + eStatIDs = []string{"STATS1", "STATS2", "STATS3", "STATS4"} + if statIDs := rtAscSrtr.sortStatIDs(); !reflect.DeepEqual(eStatIDs, statIDs) { + t.Errorf("Expecting: %v, received %v", eStatIDs, statIDs) + } +}