src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingFile.java
changeset 52850 f527b24990d7
parent 50113 caf115bb98ad
child 57360 5d043a159d5c
child 58863 c16ac7a2eba4
equal deleted inserted replaced
52849:eef755718cb2 52850:f527b24990d7
    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());