package com.linkedin.thirdeye.dashboard.views.contributor; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import com.linkedin.thirdeye.dashboard.views.TimeBucket; public class ContributionViewTableBuilder { boolean finished = false; TreeSet<TimeBucket> timeBuckets; Map<TimeBucket, DescriptiveStatistics> baselineStatsMap; Map<TimeBucket, DescriptiveStatistics> currentStatsMap; Map<TimeBucket, DescriptiveStatistics> cumulativeBaselineStatsMap; Map<TimeBucket, DescriptiveStatistics> cumulativeCurrentStatsMap; Set<String> dimensionValueSet; List<ContributionCell> cells; private String metricName; private String dimensionName; Map<TimeBucket, Map<String, ContributionCell>> timeBucketToDimensionValuesMap; public ContributionViewTableBuilder(String metricName, String dimensionName) { this.metricName = metricName; this.dimensionName = dimensionName; timeBuckets = new TreeSet<>(); baselineStatsMap = new TreeMap<>(); currentStatsMap = new TreeMap<>(); cumulativeBaselineStatsMap = new TreeMap<>(); cumulativeCurrentStatsMap = new TreeMap<>(); dimensionValueSet = new TreeSet<>(); cells = new ArrayList<>(); timeBucketToDimensionValuesMap = new HashMap<>(); } public void addEntry(String dimensionValue, TimeBucket timeBucket, Double baselineValue, Double currentValue, Double cumulativeBaselineValue, Double cumulativeCurrentValue) { if (finished) { throw new RuntimeException("Cannot add more entries since the view is already created"); } DescriptiveStatistics baselineStats; DescriptiveStatistics cumulativeCurrentStats; DescriptiveStatistics currentStats; DescriptiveStatistics cumulativeBaselineStats; timeBuckets.add(timeBucket); dimensionValueSet.add(dimensionValue); baselineStats = getStats(baselineStatsMap, timeBucket); currentStats = getStats(currentStatsMap, timeBucket); cumulativeBaselineStats = getStats(cumulativeBaselineStatsMap, timeBucket); cumulativeCurrentStats = getStats(cumulativeCurrentStatsMap, timeBucket); baselineStats.addValue(baselineValue); currentStats.addValue(currentValue); cumulativeBaselineStats.addValue(cumulativeBaselineValue); cumulativeCurrentStats.addValue(cumulativeCurrentValue); ContributionCell contributionCell = new ContributionCell(dimensionValue, timeBucket, baselineValue, currentValue, cumulativeBaselineValue, cumulativeCurrentValue); cells.add(contributionCell); Map<String, ContributionCell> map = timeBucketToDimensionValuesMap.get(timeBucket); if (map == null) { map = new HashMap<>(); timeBucketToDimensionValuesMap.put(timeBucket, map); } map.put(dimensionValue, contributionCell); } private DescriptiveStatistics getStats(Map<TimeBucket, DescriptiveStatistics> statsMap, TimeBucket timeBucket) { DescriptiveStatistics stats = statsMap.get(timeBucket); if (stats == null) { stats = new DescriptiveStatistics(); statsMap.put(timeBucket, stats); } return stats; } public ContributionViewTable build() { finished = true; for (String dimensionValue : dimensionValueSet) { ContributionCell prevCell = null; for (TimeBucket timeBucket : timeBuckets) { double baselineTotal = baselineStatsMap.get(timeBucket).getSum(); double currentTotal = currentStatsMap.get(timeBucket).getSum(); double cumulativeBaselineTotal = cumulativeBaselineStatsMap.get(timeBucket).getSum(); double cumulativeCurrentTotal = cumulativeCurrentStatsMap.get(timeBucket).getSum(); ContributionCell cell = timeBucketToDimensionValuesMap.get(timeBucket).get(dimensionValue); if (cell == null) { double cumulativeBaselineValue = 0; double cumulativeCurrentValue = 0; if (prevCell != null) { cumulativeBaselineValue = prevCell.getCumulativeBaselineValue(); cumulativeCurrentValue = prevCell.getCumulativeCurrentValue(); } cell = new ContributionCell(dimensionValue, timeBucket, 0, 0, cumulativeBaselineValue, cumulativeCurrentValue); cells.add(cell); } cell.updateContributionStats(baselineTotal, currentTotal, cumulativeBaselineTotal, cumulativeCurrentTotal); } } return new ContributionViewTable(metricName, dimensionName, cells); } public String getMetricName() { return metricName; } public String getDimensionName() { return dimensionName; } }