fork download
  1.  
  2. import java.io.StringWriter;
  3. import java.util.ArrayList;
  4. import java.util.HashMap;
  5. import java.util.Iterator;
  6. import java.util.List;
  7. import java.util.Map;
  8. import java.util.Objects;
  9. import java.util.stream.Collectors;
  10. import java.util.stream.Stream;
  11.  
  12. class Test {
  13.  
  14. static class DataPoint {
  15. private long timestamp;
  16. private Object value;
  17.  
  18. public DataPoint(long timestamp, Object value) {
  19. this.timestamp = timestamp;
  20. this.value = value;
  21. }
  22.  
  23. public long getTimestamp() {
  24. return timestamp;
  25. }
  26.  
  27. public Object getValue() {
  28. return value;
  29. }
  30.  
  31. public String toString() {
  32. return timestamp + ": " + value;
  33. }
  34. }
  35.  
  36. static class NamedKeeparator implements Iterator<DataPoint> {
  37. private final Iterator<DataPoint> delegate;
  38. private final String name;
  39. private DataPoint current;
  40.  
  41. public NamedKeeparator(String name, Iterator<DataPoint> delegate) {
  42. this.delegate = delegate;
  43. this.name = name;
  44. }
  45.  
  46. @Override
  47. public boolean hasNext() {
  48. return delegate.hasNext();
  49. }
  50.  
  51. @Override
  52. public DataPoint next() {
  53. return current = delegate.next();
  54. }
  55.  
  56. public DataPoint current() {
  57. return current;
  58. }
  59.  
  60. public void consume() {
  61. current = null;
  62. }
  63.  
  64. String getName() {
  65. return name;
  66. }
  67. }
  68.  
  69. public static void main(String args[]) {
  70. Map<String, List<DataPoint>> metriDps = new HashMap<>();
  71. String[] metricNames = new String[] {
  72. "m1", "m2", "m3"
  73. };
  74. List<DataPoint> dataPoints1 = new ArrayList<DataPoint>();
  75. dataPoints1.add(new DataPoint(0, 1));
  76. dataPoints1.add(new DataPoint(2, 1));
  77. dataPoints1.add(new DataPoint(3, 5));
  78. metriDps.put("m1", dataPoints1);
  79.  
  80. List<DataPoint> dataPoints2 = new ArrayList<DataPoint>();
  81. dataPoints2.add(new DataPoint(1, 2));
  82. dataPoints2.add(new DataPoint(2, 3));
  83. dataPoints2.add(new DataPoint(3, 5));
  84. metriDps.put("m2", dataPoints2);
  85.  
  86. List<DataPoint> dataPoints3 = new ArrayList<DataPoint>();
  87. dataPoints3.add(new DataPoint(0, 2));
  88. dataPoints3.add(new DataPoint(2, 6));
  89. dataPoints3.add(new DataPoint(4, 5));
  90. metriDps.put("m3", dataPoints3);
  91.  
  92. StringWriter writer = new StringWriter();
  93. // header
  94. writer.append("timestamp,");
  95. writer.append(Stream.of(metricNames).collect(Collectors.joining(",")));
  96. writer.append('\n');
  97.  
  98. List<NamedKeeparator> iterators = metriDps.entrySet().stream()
  99. .map(entry -> new NamedKeeparator(entry.getKey(), entry.getValue().iterator()))
  100. .collect(Collectors.toList());
  101.  
  102. List<NamedKeeparator> leastIterators = new ArrayList<>();
  103. for (;;) {
  104. leastIterators.clear();
  105. long leastValue = Long.MAX_VALUE;
  106. for (NamedKeeparator iterator : iterators) {
  107. // advance until there is some value
  108. while (iterator.current() == null && iterator.hasNext()) {
  109. iterator.next();
  110. }
  111. // build set of iterators pointing to least value
  112. if (iterator.current() != null
  113. && iterator.current().getTimestamp() <= leastValue) {
  114. if (iterator.current().getTimestamp() < leastValue) {
  115. leastValue = iterator.current().getTimestamp();
  116. leastIterators.clear();
  117. }
  118. leastIterators.add(iterator);
  119. }
  120. }
  121. // nothing -> all iterators done
  122. if (leastIterators.isEmpty())
  123. break;
  124.  
  125. // least contains now iterators for the same timestamp
  126.  
  127. // get time from the first
  128. long time = leastIterators.get(0).current().getTimestamp();
  129. writer.append(String.valueOf(time)).append(',');
  130.  
  131. // format points
  132. String points = Stream.of(metricNames)
  133. .map(metric -> leastIterators.stream()
  134. .filter(it -> it.getName().equals(metric)).findAny()
  135. .map(it -> it.current()).orElse(null))
  136. .map(point -> point != null ? String.valueOf(point.getValue()) : "")
  137. .collect(Collectors.joining(","));
  138.  
  139. writer.append(points).append('\n');
  140.  
  141. leastIterators.forEach(it -> {
  142. it.consume();
  143. });
  144. }
  145.  
  146. System.out.println(writer);
  147. }
  148.  
  149. }
  150.  
Success #stdin #stdout 0.21s 320832KB
stdin
Standard input is empty
stdout
timestamp,m1,m2,m3
0,1,,2
1,,2,
2,1,3,6
3,5,5,
4,,,5