group by multiple fields
Before we could only group by a single field. But it is acutally very useful to group by multiple fields. For example to see the graph for a small set of methods grouped by host and project.
This commit is contained in:
@@ -2,6 +2,7 @@ package org.lucares.performance.db;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -10,8 +11,8 @@ import org.lucares.pdb.api.Tags;
|
||||
|
||||
public class Grouping {
|
||||
|
||||
public static final String NO_GROUPING = null;
|
||||
public static final String DEFAULT_GROUP = "<none>";
|
||||
public static final List<String> NO_GROUPING = Collections.emptyList();
|
||||
|
||||
private final List<Group> groups = new ArrayList<>();
|
||||
|
||||
private Grouping(final Group group) {
|
||||
@@ -22,7 +23,7 @@ public class Grouping {
|
||||
this.groups.addAll(groups);
|
||||
}
|
||||
|
||||
public static Grouping groupBy(final List<PdbReader> pdbReaders, final String groupByField) {
|
||||
public static Grouping groupBy(final List<PdbReader> pdbReaders, final List<String> groupByField) {
|
||||
|
||||
final Grouping result;
|
||||
if (noGrouping(groupByField)) {
|
||||
@@ -30,33 +31,29 @@ public class Grouping {
|
||||
|
||||
result = new Grouping(group);
|
||||
} else {
|
||||
final Map<String, Group> grouping = new HashMap<>();
|
||||
final Map<Tags, Group> grouping = new HashMap<>();
|
||||
|
||||
for (final PdbReader pdbReader : pdbReaders) {
|
||||
final Tags tags = pdbReader.getPdbFile().getTags();
|
||||
final String value = tags.getValue(groupByField);
|
||||
final Tags groupTags = tags.subset(groupByField);
|
||||
|
||||
final String groupName = value != null ? value : DEFAULT_GROUP;
|
||||
|
||||
addIfNotExists(grouping, groupByField, groupName);
|
||||
grouping.get(groupName).addReader(pdbReader);
|
||||
addIfNotExists(grouping, groupTags);
|
||||
grouping.get(groupTags).addReader(pdbReader);
|
||||
}
|
||||
result = new Grouping(grouping.values());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean noGrouping(final String groupByField) {
|
||||
return groupByField == NO_GROUPING || groupByField.isEmpty();
|
||||
private static boolean noGrouping(final List<String> groupByField) {
|
||||
return groupByField == null || groupByField.isEmpty();
|
||||
}
|
||||
|
||||
private static void addIfNotExists(final Map<String, Group> grouping, final String groupByField,
|
||||
final String value) {
|
||||
if (!grouping.containsKey(value)) {
|
||||
final Tags tags = Tags.create(groupByField, value);
|
||||
private static void addIfNotExists(final Map<Tags, Group> grouping, final Tags groupTags) {
|
||||
if (!grouping.containsKey(groupTags)) {
|
||||
final List<PdbReader> readers = new ArrayList<>();
|
||||
|
||||
grouping.put(value, new Group(tags, readers));
|
||||
grouping.put(groupTags, new Group(groupTags, readers));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ public class PerformanceDb implements AutoCloseable, CollectionUtils {
|
||||
* the tag to group by
|
||||
* @return {@link Result}
|
||||
*/
|
||||
public Result get(final String query, final String groupBy) {
|
||||
public Result get(final String query, final List<String> groupBy) {
|
||||
|
||||
final List<PdbReader> pdbReaders = tagsToFile.getReaders(query);
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@ public class PerformanceDbTest {
|
||||
}
|
||||
}
|
||||
|
||||
public void testGroupBy() throws Exception {
|
||||
public void testGroupBySingleField() throws Exception {
|
||||
try (PerformanceDb db = new PerformanceDb(dataDirectory)) {
|
||||
final OffsetDateTime from = DateUtils.getDate(2016, 1, 1, 00, 00, 00);
|
||||
final OffsetDateTime to = DateUtils.getDate(2016, 1, 1, 23, 59, 50);
|
||||
@@ -177,36 +177,77 @@ public class PerformanceDbTest {
|
||||
final String key = "myKey";
|
||||
final Tags tagsOne = Tags.create(key, "one", "commonKey", "commonValue");
|
||||
final Tags tagsTwo = Tags.create(key, "two", "commonKey", "commonValue");
|
||||
final Tags tagsThree = Tags.create(key, "three", "commonKey", "commonValue");
|
||||
final Tags tagsThree = Tags.create("commonKey", "commonValue");
|
||||
final List<Entry> entriesOne = storeEntries(db, timeRange, numberOfEntries, tagsOne, 1);
|
||||
final List<Entry> entriesTwo = storeEntries(db, timeRange, numberOfEntries, tagsTwo, 2);
|
||||
final List<Entry> entriesThree = storeEntries(db, timeRange, numberOfEntries, tagsThree, 3);
|
||||
|
||||
final Result result = db.get("commonKey=commonValue", key);
|
||||
final Result result = db.get("commonKey=commonValue", Arrays.asList(key));
|
||||
|
||||
final List<GroupResult> groups = result.getGroups();
|
||||
|
||||
final List<String> actualGroup = new ArrayList<>();
|
||||
for (final GroupResult groupResult : groups) {
|
||||
final String groupedByValue = groupResult.getGroupedBy().getValue(key);
|
||||
actualGroup.add(groupedByValue);
|
||||
final Tags groupedBy = groupResult.getGroupedBy();
|
||||
|
||||
switch (groupedByValue) {
|
||||
case "one":
|
||||
if (groupedBy.equals(Tags.create(key, "one"))) {
|
||||
Assert.assertEquals(groupResult.asList(), entriesOne);
|
||||
break;
|
||||
case "two":
|
||||
Assert.assertEquals(groupResult.asList(), entriesTwo);
|
||||
break;
|
||||
case "three":
|
||||
Assert.assertEquals(groupResult.asList(), entriesThree);
|
||||
break;
|
||||
} else if (groupedBy.equals(Tags.create(key, "two"))) {
|
||||
|
||||
default:
|
||||
break;
|
||||
Assert.assertEquals(groupResult.asList(), entriesTwo);
|
||||
} else if (groupedBy.isEmpty()) {
|
||||
Assert.assertEquals(groupResult.asList(), entriesThree);
|
||||
} else {
|
||||
Assert.fail("unexpected group: " + groupResult.getGroupedBy());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testGroupByMultipleFields() throws Exception {
|
||||
try (PerformanceDb db = new PerformanceDb(dataDirectory)) {
|
||||
final OffsetDateTime from = DateUtils.getDate(2016, 1, 1, 00, 00, 00);
|
||||
final OffsetDateTime to = DateUtils.getDate(2016, 1, 1, 23, 59, 50);
|
||||
|
||||
final TimeRange timeRange = new TimeRange(from, to);
|
||||
final long numberOfEntries = timeRange.duration().toHours();
|
||||
|
||||
final String key1 = "myKey1";
|
||||
final String key2 = "myKey2";
|
||||
final Tags tagsOne = Tags.create(key1, "one", key2, "aaa", "commonKey", "commonValue");
|
||||
final Tags tagsTwoA = Tags.create(key1, "two", key2, "bbb", "commonKey", "commonValue");
|
||||
final Tags tagsTwoB = Tags.create(key1, "two", key2, "bbb", "commonKey", "commonValue");
|
||||
final Tags tagsThree = Tags.create(key1, "three", "commonKey", "commonValue");
|
||||
|
||||
final List<Entry> entriesOne = storeEntries(db, timeRange, numberOfEntries, tagsOne, 1);
|
||||
final List<Entry> entriesTwo = storeEntries(db, timeRange, numberOfEntries, tagsTwoA, 2);
|
||||
entriesTwo.addAll(storeEntries(db, timeRange, numberOfEntries, tagsTwoB, 3));
|
||||
final List<Entry> entriesThree = storeEntries(db, timeRange, numberOfEntries, tagsThree, 4);
|
||||
|
||||
final Result result = db.get("commonKey=commonValue", Arrays.asList(key1, key2));
|
||||
|
||||
final List<GroupResult> groups = result.getGroups();
|
||||
|
||||
for (final GroupResult groupResult : groups) {
|
||||
final Tags groupedBy = groupResult.getGroupedBy();
|
||||
|
||||
if (groupedBy.equals(Tags.create(key1, "one", key2, "aaa"))) {
|
||||
Assert.assertEquals(groupResult.asList(), entriesOne);
|
||||
} else if (groupedBy.equals(Tags.create(key1, "two", key2, "bbb"))) {
|
||||
// there is no defined order of the entries.
|
||||
// eventually we might return them in ascending order, but
|
||||
// that is not yet implemented
|
||||
final List<Entry> actualEntries = groupResult.asList();
|
||||
|
||||
entriesTwo.sort(EntryByDateComparator.INSTANCE);
|
||||
actualEntries.sort(EntryByDateComparator.INSTANCE);
|
||||
|
||||
Assert.assertEquals(actualEntries, entriesTwo);
|
||||
} else if (groupedBy.equals(Tags.create(key1, "three"))) {
|
||||
Assert.assertEquals(groupResult.asList(), entriesThree);
|
||||
} else {
|
||||
Assert.fail("unexpected group: " + groupedBy);
|
||||
}
|
||||
}
|
||||
Assert.assertEquals(actualGroup, Arrays.asList("one", "two", "three"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,8 +266,4 @@ public class PerformanceDbTest {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
public void testBlockingIteratorInput() throws Exception {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user