Skip to content

8259956: jdk.jfr.internal.ChunkInputStream#available should return the sum of remaining available bytes #2138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from

Conversation

D-D-H
Copy link
Contributor

@D-D-H D-D-H commented Jan 19, 2021

Could I have a review of this small fix?

In the current implementation, ChunkInputStream#available only returns the available size of the current stream, which is strange for the user.


Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed

Issue

  • JDK-8259956: jdk.jfr.internal.ChunkInputStream#available should return the sum of remaining available bytes

Reviewers

Download

$ git fetch https://git.openjdk.java.net/jdk pull/2138/head:pull/2138
$ git checkout pull/2138

@D-D-H
Copy link
Contributor Author

D-D-H commented Jan 19, 2021

/label add hotspot-jfr

@bridgekeeper
Copy link

bridgekeeper bot commented Jan 19, 2021

👋 Welcome back ddong! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk openjdk bot added the rfr Pull request is ready for review label Jan 19, 2021
@openjdk
Copy link

openjdk bot commented Jan 19, 2021

@D-D-H
The hotspot-jfr label was successfully added.

@openjdk openjdk bot added the hotspot-jfr hotspot-jfr-dev@openjdk.org label Jan 19, 2021
@mlbridge
Copy link

mlbridge bot commented Jan 19, 2021

Webrevs

@egahlin
Copy link
Member

egahlin commented Jan 19, 2021

Hi Denghui,

Looks reasonable, but I will do a proper review of this and your other PRs once everything is set for JDK 16.

Erik

@D-D-H
Copy link
Contributor Author

D-D-H commented Jan 20, 2021

Hi Denghui,

Looks reasonable, but I will do a proper review of this and your other PRs once everything is set for JDK 16.

Erik

okay, thanks :)

@egahlin
Copy link
Member

egahlin commented Feb 1, 2021

Not sure things should be changed. Javadoc for Inputstream::available() says:

"Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream."

How often the stream will block depends on the underlying BufferInputStream, so it seems correct to just delegate. Purpose of the available() method is not to return the total.

@D-D-H
Copy link
Contributor Author

D-D-H commented Feb 1, 2021

Not sure things should be changed. Javadoc for Inputstream::available() says:

"Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream."

How often the stream will block depends on the underlying BufferInputStream, so it seems correct to just delegate. Purpose of the available() method is not to return the total.

In my humble opinion, Most users always expect this method to return the total readable size, and this is achievable for this method, although the java doc does not force the implementer to do so,
it's meaningless if this method just returns the size of the current stream which is invisible to users, based on this return value, the user can hardly do anything.
On the contrary, if the total size can be returned, the user can do further operations based on this data, such as selecting an appropriate compression algorithm or discarding, etc. (Of course this is just my idea)

what do you think?

@egahlin
Copy link
Member

egahlin commented Feb 1, 2021

There is a method for finding the size of a recording, Recording::getSize(). It returns a long, which means it will work in cases where the recording is larger than 2 GB. I would recommend using it if you want to know the size in a reliable way.

That said, it will probably not hurt changing so that available() return the size of what is left unread on disk, potentially in memory in the future, or from an ongoing stream in a later release.

From what I can see, Files.newInputStream(...).available() returns the full file size. This is also what java.io.FileInputStream does and BufferInputStream delegates to available() in the wrapped stream. java.io.SequenceStream on the other hand works like ChunkInputStream today.

One problem with the implementation is that you iterate over all chunks with every call to available(). It would be nice to avoid this.

I also wonder if you considered making total a long value and check for overflow once and near the return statement?

@D-D-H
Copy link
Contributor Author

D-D-H commented Feb 2, 2021

There is a method for finding the size of a recording, Recording::getSize(). It returns a long, which means it will work in cases where the recording is larger than 2 GB. I would recommend using it if you want to know the size in a reliable way.

But if I get the data of a period of time in the past through Recoding::getStream, I cannot know its size.

One problem with the implementation is that you iterate over all chunks with every call to available(). It would be nice to avoid this.

I used "unstreamedSize" to cache the size.

I also wonder if you considered making total a long value and check for overflow once and near the return statement?

yes, good idea!

r.enable(EventNames.JavaThreadStatistics)
.withPeriod(Duration.ofMillis(100));
r.start();
File repository = Path.of(System.getProperty("jdk.jfr.repository")).toFile();
Copy link
Member

@egahlin egahlin Feb 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer a simpler and more deterministic test that executes quickly and doesn't involve timing or other events (to reduce false positives).

How about this? (haven't tried it).

     public static void main(String... args) throws Exception {
        try (Recording r = new Recording()) {
            r.start();
            try (Recording s = new Recording()) {
                s.start(); // rotate
                s.stop(); // rotate
            }
            r.stop();
            try (InputStream is = r.getStream(null, null)) {
                int left = is.available();
                if (left != r.getSize()) {
                    String msg = "Expected IS::available() " + left;
                    msg += " to equal recording size " + r.getSize();
                    throw new Exception(msg);
                }
                while (is.read() != -1) {
                    left--;
                    int available = is.available();
                    if (available != left) {
                        String msg = "Expected IS::available() to return " + left;
                        msg += ", got " + available;
                        throw new Exception(msg);
                    }
                }
            }
        }
     }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense.
Updated.

@openjdk
Copy link

openjdk bot commented Feb 3, 2021

@D-D-H This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8259956: jdk.jfr.internal.ChunkInputStream#available should return the sum of remaining available bytes

Reviewed-by: egahlin

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 295 new commits pushed to the master branch:

  • b0ee7a8: 8241995: Clarify InetSocketAddress::toString specification
  • 0ef93fe: 8259265: Refactor UncaughtExceptions shell test as java test.
  • 5324b5c: 8260998: Shenandoah: Restore reference processing statistics reporting
  • c8de943: 8260617: Merge ZipFile encoding check with the initial hash calculation
  • ae2c5f0: 8260581: IGV: enhance node search
  • 9037615: 8222850: jshell tool: Misleading cascade compiler error in switch expression with undefined vars
  • 91e6c75: 8260928: InitArrayShortSize constraint func should print a helpful error message
  • cb127a4: 8198343: Test java/awt/print/PrinterJob/TestPgfmtSetMPA.java may fail w/o printer
  • c008410: 8197825: [Test] Intermittent timeout with javax/swing JColorChooser Test
  • b9d4211: 8260193: Remove JVM_GetInterfaceVersion() and JVM_DTraceXXX
  • ... and 285 more: https://git.openjdk.java.net/jdk/compare/ae9187d757b6ed585d85c6e66105ca20bebe7bc7...master

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@egahlin) but any other Committer may sponsor as well.

➡️ To flag this PR as ready for integration with the above commit message, type /integrate in a new comment. (Afterwards, your sponsor types /sponsor in a new comment to perform the integration).

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Feb 3, 2021
@D-D-H
Copy link
Contributor Author

D-D-H commented Feb 3, 2021

/integrate

@openjdk openjdk bot added the sponsor Pull request is ready to be sponsored label Feb 3, 2021
@openjdk
Copy link

openjdk bot commented Feb 3, 2021

@D-D-H
Your change (at version 612ee6c) is now ready to be sponsored by a Committer.

@egahlin
Copy link
Member

egahlin commented Feb 4, 2021

/sponsor

To reduce noise on the mailing list, you may consider pushing all changes at once, or remove the hotspot-jfr label temporarily, so notifications are not sent when you are updating the PR.

Thanks
Erik

@openjdk openjdk bot closed this Feb 4, 2021
@openjdk openjdk bot added integrated Pull request has been integrated and removed sponsor Pull request is ready to be sponsored labels Feb 4, 2021
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Feb 4, 2021
@openjdk
Copy link

openjdk bot commented Feb 4, 2021

@egahlin @D-D-H Since your change was applied there have been 317 commits pushed to the master branch:

  • 06b33a0: 8261107: ArrayIndexOutOfBoundsException in the ICC_Profile.getInstance(InputStream)
  • 60f440d: 6436374: Graphics.setColor(null) is not documented
  • 82028e7: 8260012: Reduce inclusion of collectedHeap.hpp and heapInspection.hpp
  • 9b7a8f1: Merge
  • 1a7040e: 8259794: Remove EA from JDK 16 version string starting with Initial RC promotion on Feb 04, 2021(B35)
  • afd5eef: 8260704: ParallelGC: oldgen expansion needs release-store for _end
  • 081fa3e: 8260927: StringBuilder::insert is incorrect without Compact Strings
  • ed1a775: 8258378: Final nroff manpage update for JDK 16
  • 21f8bf4: 8257215: JFR: Events dropped when streaming over a chunk rotation
  • 0fdf9cd: 8260473: [vector] ZGC: VectorReshape test produces incorrect results with ZGC enabled
  • ... and 307 more: https://git.openjdk.java.net/jdk/compare/ae9187d757b6ed585d85c6e66105ca20bebe7bc7...master

Your commit was automatically rebased without conflicts.

Pushed as commit e8ad8b3.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

@D-D-H D-D-H deleted the JDK-8259956 branch February 5, 2021 02:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hotspot-jfr hotspot-jfr-dev@openjdk.org integrated Pull request has been integrated
Development

Successfully merging this pull request may close these issues.

2 participants