diff --git a/src/converter/one/convert/JfrConverter.java b/src/converter/one/convert/JfrConverter.java index 828b1923f..5c2ae7836 100644 --- a/src/converter/one/convert/JfrConverter.java +++ b/src/converter/one/convert/JfrConverter.java @@ -40,7 +40,7 @@ public void convert() throws IOException { protected abstract void convertChunk() throws IOException; protected EventAggregator collectEvents() throws IOException { - EventAggregator agg = new EventAggregator(args.threads, args.total); + EventAggregator agg = new EventAggregator(args.threads, args.total, args.lock ? 1e9 / jfr.ticksPerSec : 1.0); Class eventClass = args.live ? LiveObject.class : diff --git a/src/converter/one/convert/JfrToFlame.java b/src/converter/one/convert/JfrToFlame.java index e76b0b42d..788fe4dcb 100644 --- a/src/converter/one/convert/JfrToFlame.java +++ b/src/converter/one/convert/JfrToFlame.java @@ -31,10 +31,8 @@ public JfrToFlame(JfrReader jfr, Arguments args) { @Override protected void convertChunk() throws IOException { - collectEvents().forEach(new EventAggregator.Visitor() { + collectEvents().forEach(new EventAggregator.ValueVisitor() { final CallStack stack = new CallStack(); - final double ticksToNanos = 1e9 / jfr.ticksPerSec; - final boolean scale = args.total && args.lock && ticksToNanos != 1.0; @Override public void visit(Event event, long value) { @@ -68,7 +66,7 @@ public void visit(Event event, long value) { && ((AllocationSample) event).tlabSize == 0 ? TYPE_KERNEL : TYPE_INLINED); } - fg.addSample(stack, scale ? (long) (value * ticksToNanos) : value); + fg.addSample(stack, value); stack.clear(); } } diff --git a/src/converter/one/convert/JfrToPprof.java b/src/converter/one/convert/JfrToPprof.java index dcd3e30db..f75b2cd60 100644 --- a/src/converter/one/convert/JfrToPprof.java +++ b/src/converter/one/convert/JfrToPprof.java @@ -43,14 +43,12 @@ public JfrToPprof(JfrReader jfr, Arguments args) { @Override protected void convertChunk() throws IOException { - collectEvents().forEach(new EventAggregator.Visitor() { + collectEvents().forEach(new EventAggregator.ValueVisitor() { final Proto s = new Proto(100); - final double ticksToNanos = 1e9 / jfr.ticksPerSec; - final boolean scale = args.total && args.lock && ticksToNanos != 1.0; @Override public void visit(Event event, long value) { - profile.field(2, sample(s, event, scale ? (long) (value * ticksToNanos) : value)); + profile.field(2, sample(s, event, value)); s.reset(); } }); diff --git a/src/converter/one/jfr/event/EventAggregator.java b/src/converter/one/jfr/event/EventAggregator.java index ac4bb0657..12479b824 100644 --- a/src/converter/one/jfr/event/EventAggregator.java +++ b/src/converter/one/jfr/event/EventAggregator.java @@ -10,49 +10,59 @@ public class EventAggregator { private final boolean threads; private final boolean total; + private final double factor; private Event[] keys; + private long[] samples; private long[] values; private int size; - public EventAggregator(boolean threads, boolean total) { + public EventAggregator(boolean threads, boolean total, double factor) { this.threads = threads; this.total = total; + this.factor = factor; this.keys = new Event[INITIAL_CAPACITY]; + this.samples = new long[INITIAL_CAPACITY]; this.values = new long[INITIAL_CAPACITY]; } + public int size() { + return size; + } + public void collect(Event e) { int mask = keys.length - 1; int i = hashCode(e) & mask; while (keys[i] != null) { if (sameGroup(keys[i], e)) { - values[i] += total ? e.value() : e.samples(); + samples[i] += e.samples(); + values[i] += e.value(); return; } i = (i + 1) & mask; } keys[i] = e; - values[i] = total ? e.value() : e.samples(); + samples[i] = e.samples(); + values[i] = e.value(); if (++size * 2 > keys.length) { resize(keys.length * 2); } } - public long getValue(Event e) { - int mask = keys.length - 1; - int i = hashCode(e) & mask; - while (keys[i] != null && !sameGroup(keys[i], e)) { - i = (i + 1) & mask; + public void forEach(Visitor visitor) { + for (int i = 0; i < keys.length; i++) { + if (keys[i] != null) { + visitor.visit(keys[i], samples[i], values[i]); + } } - return values[i]; } - public void forEach(Visitor visitor) { + public void forEach(ValueVisitor visitor) { + double factor = total ? this.factor : 0.0; for (int i = 0; i < keys.length; i++) { if (keys[i] != null) { - visitor.visit(keys[i], values[i]); + visitor.visit(keys[i], factor == 0.0 ? samples[i] : factor == 1.0 ? values[i] : (long) (values[i] * factor)); } } } @@ -67,6 +77,7 @@ private boolean sameGroup(Event e1, Event e2) { private void resize(int newCapacity) { Event[] newKeys = new Event[newCapacity]; + long[] newSamples = new long[newCapacity]; long[] newValues = new long[newCapacity]; int mask = newKeys.length - 1; @@ -75,6 +86,7 @@ private void resize(int newCapacity) { for (int j = hashCode(keys[i]) & mask; ; j = (j + 1) & mask) { if (newKeys[j] == null) { newKeys[j] = keys[i]; + newSamples[j] = samples[i]; newValues[j] = values[i]; break; } @@ -83,10 +95,15 @@ private void resize(int newCapacity) { } keys = newKeys; + samples = newSamples; values = newValues; } public interface Visitor { + void visit(Event event, long samples, long value); + } + + public interface ValueVisitor { void visit(Event event, long value); } }