blob: ae00fdf454706ba2746762ce69ff08787642faa6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.eagle.query.aggregate.timeseries;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
public class TimeSeriesPostFlatAggregateSort {
// private static final Logger logger =
// LoggerFactory.getLogger(PostFlatAggregateSort.class);
private static SortedSet<Map.Entry<List<String>, List<Double>>> sortByValue(
Map<List<String>, List<Double>> mapForSort,
List<SortOption> sortOptions) {
SortedSet<Map.Entry<List<String>, List<Double>>> sortedEntries = new TreeSet<Map.Entry<List<String>, List<Double>>>(
new MapEntryComparator(sortOptions));
sortedEntries.addAll(mapForSort.entrySet());
return sortedEntries;
}
/**
* sort aggregated results with sort options
*
* @param entity
*/
public static List<Map.Entry<List<String>, List<double[]>>> sort(
Map<List<String>, List<Double>> mapForSort,
Map<List<String>, List<double[]>> valueMap,
List<SortOption> sortOptions, int topN) {
processIndex(sortOptions);
List<Map.Entry<List<String>, List<double[]>>> result = new ArrayList<Map.Entry<List<String>, List<double[]>>>();
SortedSet<Map.Entry<List<String>, List<Double>>> sortedSet = sortByValue(
mapForSort, sortOptions);
for (Map.Entry<List<String>, List<Double>> entry : sortedSet) {
List<String> key = entry.getKey();
List<double[]> value = valueMap.get(key);
if (value != null) {
Map.Entry<List<String>, List<double[]>> newEntry = new ImmutableEntry<List<String>, List<double[]>>(key, value);
result.add(newEntry);
if (topN > 0 && result.size() >= topN) {
break;
}
}
}
return result;
}
private static void processIndex(List<SortOption> sortOptions) {
for (int i = 0; i < sortOptions.size(); ++i) {
SortOption so = sortOptions.get(i);
so.setIndex(i);
}
}
private static class MapEntryComparator implements Comparator<Map.Entry<List<String>, List<Double>>> {
private List<SortOption> sortOptions;
public MapEntryComparator(List<SortOption> sortOptions) {
this.sortOptions = sortOptions;
}
/**
* default to sort by all groupby fields
*/
@Override
public int compare(Map.Entry<List<String>, List<Double>> e1,
Map.Entry<List<String>, List<Double>> e2) {
int r = 0;
List<String> keyList1 = e1.getKey();
List<Double> valueList1 = e1.getValue();
List<String> keyList2 = e2.getKey();
List<Double> valueList2 = e2.getValue();
for (SortOption so : sortOptions) {
int index = so.getIndex();
if (index == -1) {
continue;
}
if (!so.isInGroupby()) { // sort fields come from functions
Double value1 = valueList1.get(index);
Double value2 = valueList2.get(index);
r = value1.compareTo(value2);
} else { // sort fields come from groupby fields
String key1 = keyList1.get(index);
String key2 = keyList2.get(index);
r = key1.compareTo(key2);
}
if (r == 0) {
continue;
}
if (!so.isAscendant()) {
r = -r;
}
return r;
}
// default to sort by groupby fields ascendently
if (r == 0) { // TODO is this check necessary
return new GroupbyFieldsComparator()
.compare(keyList1, keyList2);
}
return r;
}
}
static class ImmutableEntry<K, V> implements Map.Entry<K, V>, Serializable {
private final K key;
private final V value;
ImmutableEntry(K key, V value) {
this.key = key;
this.value = value;
}
@Override
public K getKey() {
return key;
}
@Override
public V getValue() {
return value;
}
@Override
public final V setValue(V value) {
throw new UnsupportedOperationException();
}
private static final long serialVersionUID = 0;
}
}