src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ChunkHeader.java
changeset 59226 a0f39cc47387
parent 58863 c16ac7a2eba4
child 59274 eb3e2a5c2bcd
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ChunkHeader.java	Fri Nov 22 09:06:35 2019 -0500
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ChunkHeader.java	Fri Nov 22 17:20:43 2019 +0100
@@ -39,8 +39,10 @@
     private static final long CHUNK_SIZE_POSITION = 8;
     private static final long DURATION_NANOS_POSITION = 40;
     private static final long FILE_STATE_POSITION = 64;
+    private static final long FLAG_BYTE_POSITION = 67;
     private static final long METADATA_TYPE_ID = 0;
     private static final byte[] FILE_MAGIC = { 'F', 'L', 'R', '\0' };
+    private static final int MASK_FINAL_CHUNK = 1 << 1;
 
     private final short major;
     private final short minor;
@@ -58,6 +60,7 @@
     private long absoluteChunkEnd;
     private boolean isFinished;
     private boolean finished;
+    private boolean finalChunk;
 
     public ChunkHeader(RecordingInput input) throws IOException {
         this(input, 0, 0);
@@ -101,8 +104,7 @@
         Logger.log(LogTag.JFR_SYSTEM_PARSER, LogLevel.INFO, "Chunk: startTicks=" + chunkStartTicks);
         ticksPerSecond = input.readRawLong();
         Logger.log(LogTag.JFR_SYSTEM_PARSER, LogLevel.INFO, "Chunk: ticksPerSecond=" + ticksPerSecond);
-        input.readRawInt(); // features, not used
-
+        input.readRawInt(); // ignore file state and flag bits
         refresh();
         input.position(absoluteEventStart);
     }
@@ -123,6 +125,8 @@
             long durationNanos = input.readPhysicalLong();
             input.positionPhysical(absoluteChunkStart + FILE_STATE_POSITION);
             byte fileState2 =  input.readPhysicalByte();
+            input.positionPhysical(absoluteChunkStart + FLAG_BYTE_POSITION);
+            int flagByte = input.readPhysicalByte();
             if (fileState1 == fileState2) { // valid header
                 finished = fileState1 == 0;
                 if (metadataPosition != 0) {
@@ -150,6 +154,8 @@
                     Logger.log(LogTag.JFR_SYSTEM_PARSER, LogLevel.INFO, "Chunk: generation=" + fileState2);
                     Logger.log(LogTag.JFR_SYSTEM_PARSER, LogLevel.INFO, "Chunk: finished=" + isFinished);
                     Logger.log(LogTag.JFR_SYSTEM_PARSER, LogLevel.INFO, "Chunk: fileSize=" + input.size());
+                    this.finalChunk = (flagByte & MASK_FINAL_CHUNK) != 0;
+                    Logger.log(LogTag.JFR_SYSTEM_PARSER, LogLevel.INFO, "Chunk: finalChunk=" + finalChunk);
                     absoluteChunkEnd = absoluteChunkStart + chunkSize;
                     return;
                 }
@@ -183,6 +189,10 @@
         return input.getFileSize() == absoluteChunkEnd;
    }
 
+    public boolean isFinalChunk() {
+        return finalChunk;
+    }
+
     public boolean isFinished() throws IOException {
         return isFinished;
     }