30 import java.io.File; |
30 import java.io.File; |
31 import java.io.IOException; |
31 import java.io.IOException; |
32 import java.nio.file.NoSuchFileException; |
32 import java.nio.file.NoSuchFileException; |
33 import java.nio.file.Path; |
33 import java.nio.file.Path; |
34 import java.util.ArrayList; |
34 import java.util.ArrayList; |
|
35 import java.util.Collections; |
35 import java.util.HashSet; |
36 import java.util.HashSet; |
36 import java.util.List; |
37 import java.util.List; |
37 |
38 |
38 import jdk.jfr.EventType; |
39 import jdk.jfr.EventType; |
39 import jdk.jfr.internal.MetadataDescriptor; |
40 import jdk.jfr.internal.MetadataDescriptor; |
|
41 import jdk.jfr.internal.Type; |
40 import jdk.jfr.internal.consumer.ChunkHeader; |
42 import jdk.jfr.internal.consumer.ChunkHeader; |
41 import jdk.jfr.internal.consumer.RecordingInput; |
43 import jdk.jfr.internal.consumer.RecordingInput; |
|
44 import jdk.jfr.internal.consumer.RecordingInternals; |
42 |
45 |
43 /** |
46 /** |
44 * A recording file. |
47 * A recording file. |
45 * <p> |
48 * <p> |
46 * The following example shows how read and print all events in a recording file. |
49 * The following example shows how read and print all events in a recording file. |
57 * </pre> |
60 * </pre> |
58 * |
61 * |
59 * @since 9 |
62 * @since 9 |
60 */ |
63 */ |
61 public final class RecordingFile implements Closeable { |
64 public final class RecordingFile implements Closeable { |
62 |
65 static{ |
|
66 RecordingInternals.INSTANCE = new RecordingInternals() { |
|
67 public List<Type> readTypes(RecordingFile file) throws IOException { |
|
68 return file.readTypes(); |
|
69 } |
|
70 |
|
71 public boolean isLastEventInChunk(RecordingFile file) { |
|
72 return file.isLastEventInChunk; |
|
73 } |
|
74 |
|
75 @Override |
|
76 public Object getOffsetDataTime(RecordedObject event, String name) { |
|
77 return event.getOffsetDateTime(name); |
|
78 } |
|
79 |
|
80 @Override |
|
81 public void sort(List<RecordedEvent> events) { |
|
82 Collections.sort(events, (e1, e2) -> Long.compare(e1.endTime, e2.endTime)); |
|
83 } |
|
84 }; |
|
85 } |
|
86 |
|
87 private boolean isLastEventInChunk; |
63 private final File file; |
88 private final File file; |
64 private RecordingInput input; |
89 private RecordingInput input; |
65 private ChunkParser chunkParser; |
90 private ChunkParser chunkParser; |
66 private RecordedEvent nextEvent; |
91 private RecordedEvent nextEvent; |
67 private boolean eof; |
92 private boolean eof; |
96 public RecordedEvent readEvent() throws IOException { |
121 public RecordedEvent readEvent() throws IOException { |
97 if (eof) { |
122 if (eof) { |
98 ensureOpen(); |
123 ensureOpen(); |
99 throw new EOFException(); |
124 throw new EOFException(); |
100 } |
125 } |
|
126 isLastEventInChunk = false; |
101 RecordedEvent event = nextEvent; |
127 RecordedEvent event = nextEvent; |
102 nextEvent = chunkParser.readEvent(); |
128 nextEvent = chunkParser.readEvent(); |
103 if (nextEvent == null) { |
129 if (nextEvent == null) { |
|
130 isLastEventInChunk = true; |
104 findNext(); |
131 findNext(); |
105 } |
132 } |
106 return event; |
133 return event; |
107 } |
134 } |
108 |
135 |
126 * @see #hasMoreEvents() |
153 * @see #hasMoreEvents() |
127 */ |
154 */ |
128 public List<EventType> readEventTypes() throws IOException { |
155 public List<EventType> readEventTypes() throws IOException { |
129 ensureOpen(); |
156 ensureOpen(); |
130 List<EventType> types = new ArrayList<>(); |
157 List<EventType> types = new ArrayList<>(); |
|
158 HashSet<Long> foundIds = new HashSet<>(); |
|
159 try (RecordingInput ri = new RecordingInput(file)) { |
|
160 ChunkHeader ch = new ChunkHeader(ri); |
|
161 aggregateEventTypeForChunk(ch, types, foundIds); |
|
162 while (!ch.isLastChunk()) { |
|
163 ch = ch.nextHeader(); |
|
164 aggregateEventTypeForChunk(ch, types, foundIds); |
|
165 } |
|
166 } |
|
167 return types; |
|
168 } |
|
169 |
|
170 List<Type> readTypes() throws IOException { |
|
171 ensureOpen(); |
|
172 List<Type> types = new ArrayList<>(); |
131 HashSet<Long> foundIds = new HashSet<>(); |
173 HashSet<Long> foundIds = new HashSet<>(); |
132 try (RecordingInput ri = new RecordingInput(file)) { |
174 try (RecordingInput ri = new RecordingInput(file)) { |
133 ChunkHeader ch = new ChunkHeader(ri); |
175 ChunkHeader ch = new ChunkHeader(ri); |
134 aggregateTypeForChunk(ch, types, foundIds); |
176 aggregateTypeForChunk(ch, types, foundIds); |
135 while (!ch.isLastChunk()) { |
177 while (!ch.isLastChunk()) { |
138 } |
180 } |
139 } |
181 } |
140 return types; |
182 return types; |
141 } |
183 } |
142 |
184 |
143 private static void aggregateTypeForChunk(ChunkHeader ch, List<EventType> types, HashSet<Long> foundIds) throws IOException { |
185 private void aggregateTypeForChunk(ChunkHeader ch, List<Type> types, HashSet<Long> foundIds) throws IOException { |
|
186 MetadataDescriptor m = ch.readMetadata(); |
|
187 for (Type t : m.getTypes()) { |
|
188 if (!foundIds.contains(t.getId())) { |
|
189 types.add(t); |
|
190 foundIds.add(t.getId()); |
|
191 } |
|
192 } |
|
193 } |
|
194 |
|
195 private static void aggregateEventTypeForChunk(ChunkHeader ch, List<EventType> types, HashSet<Long> foundIds) throws IOException { |
144 MetadataDescriptor m = ch.readMetadata(); |
196 MetadataDescriptor m = ch.readMetadata(); |
145 for (EventType t : m.getEventTypes()) { |
197 for (EventType t : m.getEventTypes()) { |
146 if (!foundIds.contains(t.getId())) { |
198 if (!foundIds.contains(t.getId())) { |
147 types.add(t); |
199 types.add(t); |
148 foundIds.add(t.getId()); |
200 foundIds.add(t.getId()); |